[Lldb-commits] [lldb] 8470dfb - [lldb] Guard DW_OP_convert against null DWARF unit and empty stack (#207008)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Jul 6 02:50:29 PDT 2026
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 <michaelbuch12 at gmail.com>
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) {
More information about the lldb-commits
mailing list