[Lldb-commits] [lldb] [lldb] Oversized DW_OP_piece triggers an unbounded allocation and aborts LLDB (PR #209397)

Alexsander Borges Damaceno via lldb-commits lldb-commits at lists.llvm.org
Sun Jul 26 20:41:47 PDT 2026


https://github.com/AlexsanderDamaceno updated https://github.com/llvm/llvm-project/pull/209397

>From b78da1745b3d43f3f1d6d12daae5fff493fe8be2 Mon Sep 17 00:00:00 2001
From: AlexsanderDamaceno <aemgbo at gmail.com>
Date: Tue, 14 Jul 2026 05:16:18 -0300
Subject: [PATCH] E

---
 lldb/source/Expression/DWARFExpression.cpp        |  9 +++++++++
 lldb/unittests/Expression/DWARFExpressionTest.cpp | 11 +++++++++++
 2 files changed, 20 insertions(+)

diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index c4c86b408accd..b6c1e20cc99c0 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -1107,6 +1107,15 @@ static llvm::Error Evaluate_DW_OP_piece(EvalContext &eval_ctx,
   if (piece_byte_size == 0)
     return llvm::Error::success();
 
+  // A single piece of a variable's location can never legitimately be
+  // this large.
+  constexpr uint64_t kMaxDWARFPieceByteSize = 1024 * 1024 * 1024; // 1GB
+  if (piece_byte_size > kMaxDWARFPieceByteSize)
+    return llvm::createStringError("DW_OP_piece(%" PRIu64 
+                                   ") is larger than the maximum allowed "
+                                   "size of %" PRIu64 " bytes",
+                                   piece_byte_size, kMaxDWARFPieceByteSize);
+
   Value curr_piece;
 
   if (eval_ctx.stack.empty()) {
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index f552f42dcba5c..753fdd23fb3a1 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -670,6 +670,17 @@ TEST(DWARFExpression, DW_OP_piece) {
       ExpectHostAddress(expected_host_buffer));
 }
 
+TEST(DWARFExpression, DW_OP_piece_oversized) {
+  // A DW_OP_piece whose declared byte size is absurdly large (e.g. from
+  // corrupt or malicious DWARF) must be rejected with an error instead of
+  // attempting to allocate an unbounded host-side buffer, which can abort
+  // the whole debugger.
+
+  // ULEB128 encoding of 0x40000001, one byte past the 1GB piece-size limit.
+  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_piece, 0x81, 0x80, 0x80, 0x80, 0x04}),
+                       llvm::Failed());
+}
+
 TEST(DWARFExpression, DW_OP_implicit_value) {
   unsigned char bytes = 4;
 



More information about the lldb-commits mailing list