Skip to content

Commit

Permalink
[NRBF] Fuzzing non-seekable stream input (dotnet#107605)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamsitnik authored and jtschuster committed Sep 17, 2024
1 parent 78ac1bf commit 9d727af
Showing 1 changed file with 20 additions and 7 deletions.
27 changes: 20 additions & 7 deletions src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/NrbfDecoderFuzzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,23 @@ internal sealed class NrbfDecoderFuzzer : IFuzzer

public void FuzzTarget(ReadOnlySpan<byte> bytes)
{
using PooledBoundedMemory<byte> inputPoisonedAfter = PooledBoundedMemory<byte>.Rent(bytes, PoisonPagePlacement.After);
using PooledBoundedMemory<byte> inputPoisonedBefore = PooledBoundedMemory<byte>.Rent(bytes, PoisonPagePlacement.Before);
using MemoryStream streamAfter = new MemoryStream(inputPoisonedAfter.Memory.ToArray());
using MemoryStream streamBefore = new MemoryStream(inputPoisonedBefore.Memory.ToArray());
Test(bytes, PoisonPagePlacement.Before);
Test(bytes, PoisonPagePlacement.After);
}

private static void Test(ReadOnlySpan<byte> bytes, PoisonPagePlacement poisonPagePlacement)
{
using PooledBoundedMemory<byte> inputPoisoned = PooledBoundedMemory<byte>.Rent(bytes, poisonPagePlacement);

using MemoryStream seekableStream = new(inputPoisoned.Memory.ToArray());
Test(inputPoisoned.Span, seekableStream);

Test(inputPoisonedAfter.Span, streamAfter);
Test(inputPoisonedBefore.Span, streamBefore);
// NrbfDecoder has few code paths dedicated to non-seekable streams, let's test them as well.
using NonSeekableStream nonSeekableStream = new(inputPoisoned.Memory.ToArray());
Test(inputPoisoned.Span, nonSeekableStream);
}

private static void Test(Span<byte> testSpan, MemoryStream stream)
private static void Test(Span<byte> testSpan, Stream stream)
{
if (NrbfDecoder.StartsWithPayloadHeader(testSpan))
{
Expand Down Expand Up @@ -109,5 +116,11 @@ private static void Test(Span<byte> testSpan, MemoryStream stream)
catch (EndOfStreamException) { /* The end of the stream was reached before reading SerializationRecordType.MessageEnd record. */ }
}
}

private class NonSeekableStream : MemoryStream
{
public NonSeekableStream(byte[] buffer) : base(buffer) { }
public override bool CanSeek => false;
}
}
}

0 comments on commit 9d727af

Please sign in to comment.