-
Notifications
You must be signed in to change notification settings - Fork 1.8k
fix undefined 32-bit shift in dwarf LEB128 decoding #16565
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -98,7 +98,7 @@ uint64_t FIRCLSParseULEB128AndAdvance(const void** cursor) { | |||||
|
|
||||||
| *cursor += 1; | ||||||
|
|
||||||
| result |= ((0x7F & byte) << shift); | ||||||
| result |= ((uint64_t)(0x7F & byte) << shift); | ||||||
| if ((0x80 & byte) == 0) { | ||||||
| break; | ||||||
| } | ||||||
|
|
@@ -120,7 +120,7 @@ int64_t FIRCLSParseLEB128AndAdvance(const void** cursor) { | |||||
|
|
||||||
| *cursor += 1; | ||||||
|
|
||||||
| result |= ((0x7F & byte) << shift); | ||||||
| result |= ((uint64_t)(0x7F & byte) << shift); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to Limiting the loop to 8 iterations prevents correct decoding of large values and leaves the cursor in an incorrect state for subsequent DWARF parsing. Consider increasing the loop limit to |
||||||
| shift += 7; | ||||||
|
|
||||||
| /* sign bit of byte is second high order bit (0x40) */ | ||||||
|
|
@@ -131,7 +131,7 @@ int64_t FIRCLSParseLEB128AndAdvance(const void** cursor) { | |||||
|
|
||||||
| if ((shift < size) && (0x40 & byte)) { | ||||||
| // sign extend | ||||||
| result |= -(1 << shift); | ||||||
| result |= -((uint64_t)1 << shift); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Applying the unary minus operator to an unsigned operand ( A cleaner, warning-free alternative to generate the sign-extension mask is using bitwise NOT:
Suggested change
|
||||||
| } | ||||||
|
|
||||||
| return result; | ||||||
|
|
||||||
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.
While widening the shift operand to
uint64_tcorrectly prevents undefined behavior for shifts >= 32, the loop itself is still limited tosizeof(uint64_t)(8) iterations.A 64-bit integer encoded in LEB128 can require up to 10 bytes (since ceil(64 / 7) = 10). Limiting the loop to 8 iterations means any ULEB128 value >= 2^56 will be truncated, and the cursor will not be advanced past the remaining bytes, which will corrupt subsequent parsing of the DWARF stream.
Consider increasing the loop limit to
10(or defining a constant for the maximum LEB128 bytes).