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 <[email protected]>
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",

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to