GH-50592: [C++][Gandiva] fix out-of-bounds read in evaluate_return_char_length#50593
Open
Arawoof06 wants to merge 1 commit into
Open
GH-50592: [C++][Gandiva] fix out-of-bounds read in evaluate_return_char_length#50593Arawoof06 wants to merge 1 commit into
Arawoof06 wants to merge 1 commit into
Conversation
|
|
|
|
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.
Rationale for this change
evaluate_return_char_lengthsizes thelpad/rpadoutput when the fill text is more than one byte wide. It counts the fill glyphs withutf8_length_ignore_invalid, which charges an invalid or truncated glyph a single byte, then walks the fill text a second time stepping by the widthutf8_char_lengthdeclares, with no bound onfill_index. The two disagree on malformed fill text: for{0xE0, 'a', 'a'}the count is 3 glyphs so the partial-fill loop runs twice, while its first step consumes all 3 bytes and the second read lands past the end of the fill buffer. It is reached fromlpad(text, n, fill)/rpad(text, n, fill)whenfillcomes from untrusted string data. Reproduced under AddressSanitizer with that fill in an exactly-sized heap buffer, givingheap-buffer-overflow READ ... 0 bytes after 3-byte region.What changes are included in this PR?
Bound the partial-fill walk by
fill_text_lenand step over each glyph the wayutf8_length_ignore_invalidcounted it, so the two stay in sync. Well-formed fill text is unaffected: every glyph fits inside the buffer and has only continuation bytes after its lead byte, so neither the bound nor the invalid-glyph handling comes into play.Are these changes tested?
Yes.
TestStringOps.TestPadMalformedUtf8FillNoOverreadrunslpad/rpadwith the truncated fill held in an exactly-sized heap buffer so the over-read trips ASAN, and asserts the padded output. Before the fix it reportsout_len9 and trailing bytes read from past the buffer; after it reports 7. The rest ofgandiva-precompiled-teststill passes.Are there any user-facing changes?
No.
This PR contains a "Critical Fix". It fixes an out-of-bounds read in the Gandiva pad sizing helper reachable from
lpad/rpadwith crafted fill text.