-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Fix NullReferenceException and InvalidCastException in SystemClassWithMembersAndTypesRecord #121409
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
base: main
Are you sure you want to change the base?
Conversation
…hMembersAndTypesRecord Co-authored-by: stephentoub <[email protected]>
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.
Pull Request Overview
This PR fixes two security vulnerabilities found by fuzzing in the NRBF decoder when handling malformed DateTime serialization data. The fix adds proper validation to prevent InvalidCastException and NullReferenceException when processing member type information.
- Adds defensive checks to validate
BinaryTypeandAdditionalInfobefore casting in theHasMemberhelper method - Adds regression tests for both fuzzer-discovered edge cases
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/SystemClassWithMembersAndTypesRecord.cs | Adds validation to HasMember method to check BinaryType is Primitive and AdditionalInfo is not null before casting |
| src/libraries/System.Formats.Nrbf/tests/InvalidInputTests.cs | Adds two test cases for fuzzer-discovered bugs: one for incorrect BinaryType.SystemClass and one for null AdditionalInfo |
| // This test reproduces the InvalidCastException found by the fuzzer | ||
| // where dateData member has BinaryType.SystemClass instead of BinaryType.Primitive | ||
| byte[] input = Convert.FromBase64String("AAGAAAD/////AQAAAAAAAAAEAQAAAA9TeXN0ZW0uRGF0ZVRpbWUCAAAABXRpY2tzCGRhdGVEYXRhAAMJEAAAYF9qYWdnZWQGBQoKCgoHAQD3/wABAAAAAgAtAAAGCgoKCgs="); | ||
|
|
Copilot
AI
Nov 6, 2025
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.
Remove trailing whitespace from this blank line.
| // This test reproduces the NullReferenceException found by the fuzzer | ||
| // where BinaryType.String has null AdditionalInfo | ||
| byte[] input = Convert.FromBase64String("AAEAAMz/////AQAAAAAAAAAEAQAAAA9TeXN0ZW0uRGF0ZVRpbWUCAAAABXRpY2tzCGRhdGVEYXRhAAEJEAAAYF+5MtwIAABgX7k2sLCwsLCwsLCwsLCwsLCwsLCwsNHcCAk="); | ||
|
|
Copilot
AI
Nov 6, 2025
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.
Remove trailing whitespace from this blank line.
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.
@copilot apply changes based on this feedback
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.
Done in 924866d
Co-authored-by: stephentoub <[email protected]>
adamsitnik
left a comment
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.
@copilot please take a look at my comments.
| { | ||
| // This test reproduces the InvalidCastException found by the fuzzer | ||
| // where dateData member has BinaryType.SystemClass instead of BinaryType.Primitive | ||
| byte[] input = Convert.FromBase64String("AAGAAAD/////AQAAAAAAAAAEAQAAAA9TeXN0ZW0uRGF0ZVRpbWUCAAAABXRpY2tzCGRhdGVEYXRhAAMJEAAAYF9qYWdnZWQGBQoKCgoHAQD3/wABAAAAAgAtAAAGCgoKCgs="); |
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.
In the reported issue, the input string is different. It does not end with GCgoKCgs=, but GCgoKCAs= (g => A).
Please use the exact string from the bug report.
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.
Fixed in f3ff132. The tests now use BinaryWriter to construct the payload, making it clearer what the test data contains.
| { | ||
| // This test reproduces the NullReferenceException found by the fuzzer | ||
| // where BinaryType.String has null AdditionalInfo | ||
| byte[] input = Convert.FromBase64String("AAEAAMz/////AQAAAAAAAAAEAQAAAA9TeXN0ZW0uRGF0ZVRpbWUCAAAABXRpY2tzCGRhdGVEYXRhAAEJEAAAYF+5MtwIAABgX7k2sLCwsLCwsLCwsLCwsLCwsLCwsNHcCAk="); |
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.
Using direct output from the Fuzzer is acceptable, but it would be nicer to create the payload in a way other tests in this class do it: write everything using BinaryWriter and add comments for crucial parts. It would be easier to understand for the humans what the input actually contains (here I need to rely on a comment that may not be true).
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.
Done in f3ff132. The tests now follow the same pattern as other tests in the class, using BinaryWriter with comments explaining each part of the payload.
Co-authored-by: adamsitnik <[email protected]>
| Assert.NotNull(exception); | ||
| Assert.IsNotType<InvalidCastException>(exception); | ||
| Assert.IsNotType<NullReferenceException>(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.
@adamsitnik, just fyi, I copied these tests locally without the fix and verified they both fail.
Fix NullReferenceException and InvalidCastException in SystemClassWithMembersAndTypesRecord
HasMemberlocal function inSystemClassWithMembersAndTypesRecord.DecodecastsAdditionalInfotoPrimitiveTypewithout checking if theBinaryTypeisPrimitiveBinaryTypeisSystemClass,AdditionalInfois aTypeName, not aPrimitiveType, causing NullReferenceException or InvalidCastExceptionHasMemberfunction to checkBinaryTypebefore castingOriginal prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.