llvm-project
414b4a91 - [lldb][DIL] Validate bitfield extraction ranges (#213055)

Commit
16 days ago
[lldb][DIL] Validate bitfield extraction ranges (#213055) The DIL bitfield extraction operator `base[high:low]` creates a synthetic bitfield child without validating the requested range. Three malformed ranges reach the data layer and either return nonsense or crash. Reproduced with a 32-bit `int value` and DIL enabled: ``` (lldb) settings set target.experimental.use-DIL true (lldb) frame variable 'value[-1:0]' (int:2) value[-1:0] = 2 ``` A negative index is accepted and produces a meaningless child. `first_index`/`last_index` are signed `int64_t`, but `GetSyntheticBitFieldChild` takes `uint32_t`, so `-1` silently wraps to a huge unsigned offset. ``` (lldb) frame variable 'value[0:64]' Assertion failed: (bitfield_bit_size <= 64), function GetMaxU64Bitfield, file DataExtractor.cpp, line 580. ``` A width greater than 64 bits aborts. `DataExtractor::GetMaxU64Bitfield` only supports up to 64 bits: it asserts in an assertions build and otherwise performs an out-of-bounds shift. A 32-bit `value` with range `[0:64]` is 65 bits, enough to trip it. ``` (lldb) frame variable 'value[100:50]' (int:51) value[100:50] = 0 ``` A high index past the base object's storage returns a garbage child in a normal build. Under UBSan the read/format path shifts by an oversized amount derived from the offset: ``` (lldb) frame variable 'value[100:50]' DataExtractor.cpp:591:12: runtime error: shift exponent 234 is too large for 64-bit type 'uint64_t' ``` Reject all three in the DIL evaluator before the synthetic child is created: a negative `first_index`/`last_index`, a normalized width greater than 64 bits, and a high index at or beyond the base object's bit size (queried with `GetCompilerType().GetBitSize`). Each returns a `DILDiagnosticError` with a clear message. Valid in-range extractions are unaffected. Adds the three malformed ranges to the DIL bitfield extraction API test (`TestFrameVarDILBitFieldExtraction`). Without the fix the test fails on the first case (`value[-1:0]` is expected to error but succeeds); the `[0:64]` case additionally asserts and the `[100:50]` case is a UBSan shift-out-of-bounds.
Author
Parents
Loading