[Lldb-commits] [lldb] [lldb] Reject DW_OP_deref_size with size 0 (PR #205911)
Yao Qi via lldb-commits
lldb-commits at lists.llvm.org
Thu Jun 25 13:48:02 PDT 2026
https://github.com/qiyao created https://github.com/llvm/llvm-project/pull/205911
`Evaluate_DW_OP_deref` validated that the dereference size was `<= 8` but
not that it was non-zero. The DWARF expression evaluator parses
untrusted operands, so a `DW_OP_deref_size` with size operand `0` is
reachable (it is hit by the lldb-dwarf-expression-fuzzer).
A zero dereference size flows into `DerefSizeExtractDataHelper`, which
constructs a `DataExtractor` with `addr_size == 0` and aborts on its
assertion. The unit test that feeds `DW_OP_lit0, DW_OP_deref_size, 0x00`
shows the crash:
```
[ RUN ] DWARFExpressionMockProcessTest.DW_OP_deref_size_zero
Assertion failed: (addr_size >= 1 && addr_size <= 8), function
DataExtractor, file DataExtractor.cpp, line 134.
#8 DataExtractor::DataExtractor(...)
#11 DWARFExpression::Evaluate(...)
```
Reject a zero dereference size with an error, alongside the existing
`size > 8` check.
Adds `DWARFExpressionMockProcessTest.DW_OP_deref_size_zero`, which aborts
on the assertion above without the fix.
>From e0fe339d7039135cc20d95831805fceb23dd6e95 Mon Sep 17 00:00:00 2001
From: Yao Qi <yao_qi at apple.com>
Date: Wed, 24 Jun 2026 18:27:22 +0100
Subject: [PATCH] [lldb] Reject DW_OP_deref_size with size 0
`Evaluate_DW_OP_deref` validated that the dereference size was `<= 8` but
not that it was non-zero. The DWARF expression evaluator parses
untrusted operands, so a `DW_OP_deref_size` with size operand `0` is
reachable (it is hit by the lldb-dwarf-expression-fuzzer).
A zero dereference size flows into `DerefSizeExtractDataHelper`, which
constructs a `DataExtractor` with `addr_size == 0` and aborts on its
assertion. The unit test that feeds `DW_OP_lit0, DW_OP_deref_size, 0x00`
shows the crash:
```
[ RUN ] DWARFExpressionMockProcessTest.DW_OP_deref_size_zero
Assertion failed: (addr_size >= 1 && addr_size <= 8), function
DataExtractor, file DataExtractor.cpp, line 134.
#8 DataExtractor::DataExtractor(...)
#11 DWARFExpression::Evaluate(...)
```
Reject a zero dereference size with an error, alongside the existing
`size > 8` check.
Adds `DWARFExpressionMockProcessTest.DW_OP_deref_size_zero`, which aborts
on the assertion above without the fix.
---
lldb/source/Expression/DWARFExpression.cpp | 2 +-
.../unittests/Expression/DWARFExpressionTest.cpp | 16 ++++++++++++++++
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 7966673bb65ed..3e650c8d6afb2 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -931,7 +931,7 @@ static llvm::Error Evaluate_DW_OP_deref(EvalContext &eval_ctx,
if (eval_ctx.stack.empty())
return llvm::createStringError("expression stack empty for %s", op_name);
- if (size > 8)
+ if (size == 0 || size > 8)
return llvm::createStringError("Invalid address size for %s: %u", op_name,
size);
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index 7feacb2b9da24..5e8ad3d348c5d 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -1113,6 +1113,22 @@ TEST_F(DWARFExpressionMockProcessTest, DW_OP_regx) {
ExpectScalar(0xBEEF, Value::ContextType::RegisterInfo));
}
+TEST_F(DWARFExpressionMockProcessTest, DW_OP_deref_size_zero) {
+ // DW_OP_deref_size with size 0 must report an error instead of constructing
+ // a DataExtractor with addr_size 0 (caught by lldb-dwarf-expression-fuzzer:
+ // assertion failure in DataExtractor / DerefSizeExtractDataHelper).
+ TestContext ctx;
+ MockMemory::Map mem;
+ mem[{lldb::addr_t(0), size_t(0)}] = {};
+ ASSERT_TRUE(
+ CreateTestContext(&ctx, "i386-pc-linux", std::nullopt, MockMemory(mem)));
+ ExecutionContext exe_ctx(ctx.process_sp);
+ EXPECT_THAT_ERROR(Evaluate({DW_OP_lit0, DW_OP_deref_size, 0x00}, {}, {},
+ &exe_ctx, ctx.reg_ctx_sp.get())
+ .takeError(),
+ llvm::Failed());
+}
+
TEST_F(DWARFExpressionMockProcessTest, DW_OP_breg0) {
TestContext ctx;
ASSERT_TRUE(CreateTestContext(&ctx, "i386-pc-linux",
More information about the lldb-commits
mailing list