[all-commits] [llvm/llvm-project] 8014a1: [Support] Fix undefined shift in decodeULEB128/dec...
Yao Qi via All-commits
all-commits at lists.llvm.org
Mon Jul 6 14:05:47 PDT 2026
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 8014a1d208f0f9e58cfeaf022517cf3d69257bff
https://github.com/llvm/llvm-project/commit/8014a1d208f0f9e58cfeaf022517cf3d69257bff
Author: Yao Qi <yao_qi at apple.com>
Date: 2026-07-06 (Mon, 06 Jul 2026)
Changed paths:
M llvm/include/llvm/Support/LEB128.h
M llvm/unittests/Support/LEB128Test.cpp
Log Message:
-----------
[Support] Fix undefined shift in decodeULEB128/decodeSLEB128 for overlong encodings (#205907)
When a (signed or unsigned) LEB128 value is encoded with extra trailing
bytes that only carry zero- or sign-extension, the decode loop could
keep
running with the shift amount at 64 or beyond and then evaluate
`Slice << Shift`, which is undefined behavior for a 64-bit type.
The DWARF expression parser feeds attacker-controlled LEB128 operands
(such as `DW_OP_bregN` / `DW_OP_constu`) through
`DataExtractor::getULEB128` / `getSLEB128`, so the
`lldb-dwarf-expression-fuzzer` reaches this under UBSan. The unsigned
case:
```
LEB128.h:152:20: runtime error: shift exponent 70 is too large for
64-bit type 'uint64_t' (aka 'unsigned long long')
#0 llvm::decodeULEB128(...) LEB128.h:152
#1 getLEB128<unsigned long long>(...) DataExtractor.cpp:227
#2 llvm::DataExtractor::getULEB128(...) DataExtractor.cpp:241
#3 llvm::DWARFExpression::Operation::extract(...) DWARFExpression.cpp:218
#7 lldb_private::DWARFExpression::Evaluate(...) DWARFExpression.cpp:1333
#9 LLVMFuzzerTestOneInput lldb-dwarf-expression-fuzzer.cpp:83
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior LEB128.h:152:20
```
and the signed case, reached the same way:
```
LEB128.h:190:20: runtime error: shift exponent 70 is too large for
64-bit type 'uint64_t' (aka 'unsigned long long')
#0 llvm::decodeSLEB128(...) LEB128.h:190
#1 getLEB128<long long>(...) DataExtractor.cpp:227
#2 llvm::DataExtractor::getSLEB128(...) DataExtractor.cpp:245
#3 llvm::DWARFExpression::Operation::extract(...) DWARFExpression.cpp:216
#7 lldb_private::DWARFExpression::Evaluate(...) DWARFExpression.cpp:1333
```
The existing range checks already guarantee that once `Shift` reaches 64
the remaining bytes are pure extension and contribute nothing to the
result, so skip the accumulating shift in that case. Decoded values are
unchanged for all well-formed inputs.
Adds overlong-encoding regression cases to `LEB128Test`. Without the fix
the signed case is the UBSan diagnostic above in a sanitizer build, and
in a normal build the unsigned case also decodes to the wrong value (the
overlong `1` decodes as `11`).
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list