Add integer overflow guards to upb buffer growth functions#26513
Open
kodareef5 wants to merge 2 commits intoprotocolbuffers:mainfrom
Open
Add integer overflow guards to upb buffer growth functions#26513kodareef5 wants to merge 2 commits intoprotocolbuffers:mainfrom
kodareef5 wants to merge 2 commits intoprotocolbuffers:mainfrom
Conversation
upb_String_Append (upb/io/string.h) and jsondec_resize (upb/json/decode.c) perform unchecked arithmetic that can overflow size_t during buffer growth: - upb_String_Append: size_ + size can wrap, causing the capacity check to pass incorrectly and memcpy to write past the buffer. The doubling 2 * (size_ + size) + 1 can also wrap. - jsondec_resize: 2 * oldsize can wrap to 0 when oldsize > SIZE_MAX/2, causing the buffer to shrink instead of grow. Add overflow checks before the arithmetic in both functions. On overflow, upb_String_Append returns false and jsondec_resize reports an error. Add unit tests demonstrating that the overflow check fires correctly and that normal operations are unaffected.
Two additional sites with unchecked buffer doubling: - upb/reflection/desc_state.c:24-25: bufsize *= 2 without overflow check, plus unsigned underflow in oldbufsize - used comparison. Add used > oldbufsize guard and SIZE_MAX/2 check before doubling. - upb/message/array.c:127: while loop doubling new_capacity without overflow check. If min_capacity is large, new_capacity wraps to 0. Add SIZE_MAX/2 check inside the loop.
Contributor
Author
|
@themavik Thanks for the thorough review. Good catch on the Regarding CI: the "Set Variables" / "All Blocking Tests (fork)" failure appears to be a fork permissions issue rather than a code problem — the workflow can't access required secrets from a fork. The actual test suite can't run in this context. If a maintainer can confirm or retrigger from the upstream side, that would help. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
upb_String_Appendandjsondec_resizeperform unchecked arithmetic during buffer growth that can overflowsize_t:upb/io/string.h —
upb_String_Appendsize_ + sizecan wrap on 32-bit platforms when the existing string is large and the append size is large. When it wraps, the capacity check at line 87 passes incorrectly (the wrapped sum is smaller than capacity), andmemcpywrites past the allocated buffer. The subsequent2 * (size_ + size) + 1compounds the overflow.Added two guards:
size > SIZE_MAX - s->size_before the additionsum > (SIZE_MAX - 1) / 2before the doublingOn overflow,
upb_String_Appendreturnsfalseinstead of corrupting memory.upb/json/decode.c —
jsondec_resize2 * oldsizewraps to 0 whenoldsize > SIZE_MAX / 2.UPB_MAX(8, 0)then selects 8, and the buffer is reallocated to 8 bytes while existing data may be much larger.Added a guard: check
oldsize > SIZE_MAX / 2before doubling, and report an error viajsondec_erron overflow.Tests
Added two tests to
upb/io/string_test.cc:AppendOverflowReturnsFailure— verifies that an append causingsize_ + sizeto wrap returnsfalseand leaves the string unchangedAppendNormalStillWorks— verifies normal appends are unaffectedAll existing tests pass (
//upb/io:string_test,//upb/json:decode_test).