Author: Yao Qi Date: 2026-07-06T10:50:24+01:00 New Revision: 8470dfb1e6190cc42c3eb151884533b8b4aba7e6
URL: https://github.com/llvm/llvm-project/commit/8470dfb1e6190cc42c3eb151884533b8b4aba7e6 DIFF: https://github.com/llvm/llvm-project/commit/8470dfb1e6190cc42c3eb151884533b8b4aba7e6.diff LOG: [lldb] Guard DW_OP_convert against null DWARF unit and empty stack (#207008) `Evaluate_DW_OP_convert` dereferenced `eval_ctx.dwarf_cu` (the `DWARFExpression` Delegate) whenever the operand DIE offset was non-zero, and unconditionally read `eval_ctx.stack.back()`. When a DWARF expression is evaluated without a DWARF unit (as the lldb-dwarf-expression-fuzzer does), two operand shapes crash: - `DW_OP_convert` with a non-zero offset calls `dwarf_cu->GetDIEBitSizeAndSign(...)` on a null Delegate. - `DW_OP_convert` with nothing on the stack reads the back of an empty vector. The unit test feeds both with `dwarf_cu == nullptr` and crashes: ``` [ RUN ] DWARFExpression.DW_OP_convert #2 SignalHandler(int, __siginfo*, void*) #4 DWARFExpression::Evaluate(...) #5 Evaluate(ArrayRef<unsigned char>, ...) ``` (SIGSEGV, the process aborts.) Bail out with an error when the stack is empty, and when a non-zero DIE offset is requested without a DWARF unit, instead of crashing. Extends `DWARFExpression.DW_OP_convert` with these two cases, which crash without the fix. --------- Co-authored-by: Michael Buch <[email protected]> Added: Modified: lldb/source/Expression/DWARFExpression.cpp lldb/unittests/Expression/DWARFExpressionTest.cpp Removed: ################################################################################ diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index 5a3c99caeb1bb..985a2dfecd38f 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -1214,6 +1214,9 @@ static llvm::Error Evaluate_DW_OP_convert(EvalContext &eval_ctx, if (!bit_size) return llvm::createStringError("unspecified architecture"); } else { + if (!eval_ctx.dwarf_cu) + return llvm::createStringError( + "DW_OP_convert with a DIE offset requires a DWARF unit"); auto bit_size_sign_or_err = eval_ctx.dwarf_cu->GetDIEBitSizeAndSign(relative_die_offset); if (!bit_size_sign_or_err) diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp index 305c4af2582db..75162ca0b5f3e 100644 --- a/lldb/unittests/Expression/DWARFExpressionTest.cpp +++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp @@ -574,6 +574,19 @@ TEST(DWARFExpression, DW_OP_convert) { EXPECT_THAT_ERROR( t.Eval({DW_OP_const1s, 'X', DW_OP_convert, 0x1d}).takeError(), llvm::Failed()); + + // A non-zero DIE offset with no DWARF unit. + EXPECT_THAT_ERROR( + Evaluate({DW_OP_const1s, 'X', DW_OP_convert, 0x01}, nullptr, nullptr) + .takeError(), + llvm::FailedWithMessage( + "DW_OP_convert with a DIE offset requires a DWARF unit")); + + // DW_OP_convert with an empty stack. + EXPECT_THAT_ERROR( + Evaluate({DW_OP_convert, 0x00}, nullptr, nullptr).takeError(), + llvm::FailedWithMessage("DW_OP_convert needs at least 1 stack entries " + "(stack has 0 entries)")); } TEST(DWARFExpression, DW_OP_stack_value) { _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
