C#: fix IndexOutOfRangeException in ReadRawByte on truncated messages#26914
C#: fix IndexOutOfRangeException in ReadRawByte on truncated messages#26914pawlos wants to merge 1 commit intoprotocolbuffers:mainfrom
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
I'm not on the protobuf team and don't have time to review this right now. I'll get to it at some point if I can, but it won't be imminently. |
c21d591 to
8fcb410
Compare
|
I've had a quick look at this now, and I'm not yet convinced the fix is right - if the |
You're right. It probably just masks the real issue. I'll have another look too. |
|
Stack of where I think things are going wrong:
I wasn't involved in writing |
8fcb410 to
75ae10e
Compare
Thanks for the pointer @jskeet! I've pushed a new commit that does the PushLimit arithmetic in long so state.currentLimit can't go negative, and reverted the >= guard in ReadRawByte. Went with widening over checked {} to keep the existing TruncatedMessage() exception path - hope this addresses the underlying issue. |
| throw InvalidProtocolBufferException.NegativeSize(); | ||
| } | ||
| byteLimit += state.totalBytesRetired + state.bufferPos; | ||
| long absoluteLimit = (long)byteLimit + state.totalBytesRetired + state.bufferPos; |
There was a problem hiding this comment.
Possibly add a comment to explain why we're doing this? (It looks right to me though.)
Compute the absolute limit in long arithmetic so overflow no longer leaves state.currentLimit negative. Fixes protocolbuffers#26856
75ae10e to
355e425
Compare
jskeet
left a comment
There was a problem hiding this comment.
That's great, thanks. I'll add another reviewer from the protobuf team.
|
@mkruskal-google This looks good to me, and has appropriate tests. |
Summary
A near-int.MaxValue length varint overflows PushLimit, corrupting bufferSize to a negative value. ReadRawByte's == guard then never triggers RefillBuffer, causing an out-of-bounds read instead of InvalidProtocolBufferException.TruncatedMessage().
Fix
change == to >= in ReadRawByte. Regression tests added for all four affected slow-path variants.
Tests
Added
TruncatedMessageWithLargeInnerLengthThrowsInvalidProtocolBufferExceptionwith 4 test cases.Fixes #26856