-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[NRBF] Fix bugs discovered by the fuzzer #107368
Conversation
… when the referenced record is missing or it points to a record of different type
… it's being thrown by BinaryReader (or sth else that we use)
Tagging subscribers to 'binaryformatter-migration': @adamsitnik, @bartonjs, @jeffhandley, @terrajobst |
{ | ||
return Decode(reader, options ?? new(), out recordMap); | ||
} | ||
catch (FormatException) // can be thrown by various BinaryReader methods |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pass to inner exception?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't do that on purpose, to avoid leaking any information from the inner exception that could be attacker controlled (like some weird string that could somehow affect the log file).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adamsitnik somehow cannot run the fuzzer locally with this fix, had cherry-picked all commits still see the |
Anyway there is one thing that is not fixed, getting InvalidCastExeption when there is no valid header, on: runtime/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/NrbfDecoder.cs Line 169 in bc3f715
I think decoder should throw when there is no header |
|
In your PR, you are referencing the NuGet package, not the local project:
What I did to get this working (it's ugly, there must be a better way):
<ItemGroup>
<Reference Include="System.Formats.Nrbf">
<HintPath>..\..\..\..\artifacts\bin\System.Formats.Nrbf\Debug\net8.0\System.Formats.Nrbf.dll</HintPath>
</Reference>
</ItemGroup>
.\dotnet.cmd build .\src\libraries\System.Formats.Nrbf\System.Formats.Nrbf.sln
D:\projects\runtime\dotnet.cmd publish -o publish; publish/DotnetFuzzing.exe prepare-onefuzz deployment
.\deployment\NrbfDecoderFuzzer\local-run.bat |
It will (I have added the fix for that with a test in my first commit), the More info: the runtime/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/NrbfDecoder.cs Lines 216 to 217 in 88f9aba
The fuzzer was smart enough to generate a value that made it pass (64 IIRC), I have simply added a check that rejects values out of the enum range: runtime/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/Utils/BinaryReaderExtensions.cs Lines 21 to 23 in bc3f715
|
…en parsing the decimal fails
Local testing unblocked with this, thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixes LGTM and the fuzzer runs more stable with the fix, thanks!
|
|
13422c2
to
acfd78e
Compare
|
…ad (so far an ArgumentException was thrown)
@MihuBot fuzz NrbfDecoder |
/ba-g the one unknown CI failure is unrelated and the failure log has no any info for filing an issue |
* bug #1: don't allow for values out of the SerializationRecordType enum range * bug #2: throw SerializationException rather than KeyNotFoundException when the referenced record is missing or it points to a record of different type * bug #3: throw SerializationException rather than FormatException when it's being thrown by BinaryReader (or sth else that we use) * bug #4: document the fact that IOException can be thrown * bug #5: throw SerializationException rather than OverflowException when parsing the decimal fails * bug #6: 0 and 17 are illegal values for PrimitiveType enum * bug #7: throw SerializationException when a surrogate character is read (so far an ArgumentException was thrown) # Conflicts: # src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/NrbfDecoder.cs
* bug #1: don't allow for values out of the SerializationRecordType enum range * bug dotnet#2: throw SerializationException rather than KeyNotFoundException when the referenced record is missing or it points to a record of different type * bug dotnet#3: throw SerializationException rather than FormatException when it's being thrown by BinaryReader (or sth else that we use) * bug dotnet#4: document the fact that IOException can be thrown * bug dotnet#5: throw SerializationException rather than OverflowException when parsing the decimal fails * bug dotnet#6: 0 and 17 are illegal values for PrimitiveType enum * bug dotnet#7: throw SerializationException when a surrogate character is read (so far an ArgumentException was thrown)
* [NRBF] Don't use Unsafe.As when decoding DateTime(s) (#105749) * Add NrbfDecoder Fuzzer (#107385) * [NRBF] Fix bugs discovered by the fuzzer (#107368) * bug #1: don't allow for values out of the SerializationRecordType enum range * bug #2: throw SerializationException rather than KeyNotFoundException when the referenced record is missing or it points to a record of different type * bug #3: throw SerializationException rather than FormatException when it's being thrown by BinaryReader (or sth else that we use) * bug #4: document the fact that IOException can be thrown * bug #5: throw SerializationException rather than OverflowException when parsing the decimal fails * bug #6: 0 and 17 are illegal values for PrimitiveType enum * bug #7: throw SerializationException when a surrogate character is read (so far an ArgumentException was thrown) # Conflicts: # src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/NrbfDecoder.cs * [NRBF] throw SerializationException when a surrogate character is read (#107532) (so far an ArgumentException was thrown) * [NRBF] Fuzzing non-seekable stream input (#107605) * [NRBF] More bug fixes (#107682) - Don't use `Debug.Fail` not followed by an exception (it may cause problems for apps deployed in Debug) - avoid Int32 overflow - throw for unexpected enum values just in case parsing has not rejected them - validate the number of chars read by BinaryReader.ReadChars - pass serialization record id to ex message - return false rather than throw EndOfStreamException when provided Stream has not enough data - don't restore the position in finally - limit max SZ and MD array length to Array.MaxLength, stop using LinkedList<T> as List<T> will be able to hold all elements now - remove internal enum values that were always illegal, but needed to be handled everywhere - Fix DebuggerDisplay * [NRBF] Comments and bug fixes from internal code review (#107735) * copy comments and asserts from Levis internal code review * apply Levis suggestion: don't store Array.MaxLength as a const, as it may change in the future * add missing and fix some of the existing comments * first bug fix: SerializationRecord.TypeNameMatches should throw ArgumentNullException for null Type argument * second bug fix: SerializationRecord.TypeNameMatches should know the difference between SZArray and single-dimension, non-zero offset arrays (example: int[] and int[*]) * third bug fix: don't cast bytes to booleans * fourth bug fix: don't cast bytes to DateTimes * add one test case that I've forgot in previous PR # Conflicts: # src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/SerializationRecord.cs * [NRBF] Address issues discovered by Threat Model (#106629) * introduce ArrayRecord.FlattenedLength * do not include invalid Type or Assembly names in the exception messages, as it's most likely corrupted/tampered/malicious data and could be used as a vector of attack. * It is possible to have binary array records have an element type of array without being marked as jagged --------- Co-authored-by: Buyaa Namnan <bunamnan@microsoft.com>
* bug #1: don't allow for values out of the SerializationRecordType enum range * bug #2: throw SerializationException rather than KeyNotFoundException when the referenced record is missing or it points to a record of different type * bug #3: throw SerializationException rather than FormatException when it's being thrown by BinaryReader (or sth else that we use) * bug dotnet#4: document the fact that IOException can be thrown * bug dotnet#5: throw SerializationException rather than OverflowException when parsing the decimal fails * bug dotnet#6: 0 and 17 are illegal values for PrimitiveType enum * bug dotnet#7: throw SerializationException when a surrogate character is read (so far an ArgumentException was thrown)
SerializationRecordType
enum range (I've checked the parsing of all other enums and they are already very defensive, it seems to be the only enum where we were not defensive enough)SerializationException
rather thanKeyNotFoundException
when the referenced record is missing or it points to a record of different type (SerializationException
is what we promise in the docs)SerializationException
rather thanFormatException
when it's being thrown byBinaryReader
(or sth else that we use)IOException
can be thrownSerializationException
rather thanOverflowException
when parsing the decimal fails