[Lldb-commits] [lldb] 0fa3320 - [lldb] reject `.debug_arange` sections with nonzero segment size

Luke Drummond via lldb-commits lldb-commits at lists.llvm.org
Thu Mar 12 05:23:19 PDT 2020


Author: Luke Drummond
Date: 2020-03-12T12:22:50Z
New Revision: 0fa3320931e93d658f68c1f19eb45b922158b61e

URL: https://github.com/llvm/llvm-project/commit/0fa3320931e93d658f68c1f19eb45b922158b61e
DIFF: https://github.com/llvm/llvm-project/commit/0fa3320931e93d658f68c1f19eb45b922158b61e.diff

LOG: [lldb] reject `.debug_arange` sections with nonzero segment size

If a producer emits a nonzero segment size, `lldb` will silently read
incorrect values and crash, or do something worse later as the tuple
size is expected to be 2, rather than 3.

Neither LLVM, nor GCC produce segmented aranges, but this dangerous case
should still be checked and handled.

Reviewed by: clayborg, labath
Differential Revision: https://reviews.llvm.org/D75925
Subscribers: lldb-commits
Tags: #lldb

Added: 
    

Modified: 
    lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
    lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
index b3f056d75593..728cefe620a5 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
@@ -63,7 +63,8 @@ llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data,
   // 1 - the version looks good
   // 2 - the address byte size looks plausible
   // 3 - the length seems to make sense
-  // size looks plausible
+  // 4 - size looks plausible
+  // 5 - the arange tuples do not contain a segment field
   if (m_header.version < 2 || m_header.version > 5)
     return llvm::make_error<llvm::object::GenericBinaryError>(
         "Invalid arange header version");
@@ -81,6 +82,10 @@ llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data,
     return llvm::make_error<llvm::object::GenericBinaryError>(
         "Invalid arange header length");
 
+  if (m_header.seg_size)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "segmented arange entries are not supported");
+
   // The first tuple following the header in each set begins at an offset
   // that is a multiple of the size of a single tuple (that is, twice the
   // size of an address). The header is padded, if necessary, to the

diff  --git a/lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp b/lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp
index c971eda2d46e..f1010a100bfd 100644
--- a/lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp
@@ -18,6 +18,7 @@
 #include "Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h"
 #include "Plugins/SymbolFile/DWARF/DWARFDataExtractor.h"
 #include "Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h"
 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
 #include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
@@ -310,3 +311,38 @@ TEST_F(SymbolFileDWARFTests, TestAbbrevMissingTerminator) {
   EXPECT_EQ("abbreviation declaration attribute list not terminated with a "
             "null entry", llvm::toString(std::move(error)));
 }
+
+TEST_F(SymbolFileDWARFTests, ParseArangesNonzeroSegmentSize) {
+  // This `.debug_aranges` table header is a valid 32bit big-endian section
+  // according to the DWARFv5 spec:6.2.1, but contains segment selectors which
+  // are not supported by lldb, and should be gracefully rejected
+  const unsigned char binary_data[] = {
+      0, 0, 0, 41, // unit_length (length field not including this field itself)
+      0, 2,        // DWARF version number (half)
+      0, 0, 0, 0, // offset into the .debug_info_table (ignored for the purposes
+                  // of this test
+      4,          // address size
+      1,          // segment size
+      // alignment for the first tuple which "begins at an offset that is a
+      // multiple of the size of a single tuple". Tuples are nine bytes in this
+      // example.
+      0, 0, 0, 0, 0, 0,
+      // BEGIN TUPLES
+      1, 0, 0, 0, 4, 0, 0, 0,
+      1, // a 1byte object starting at address 4 in segment 1
+      0, 0, 0, 0, 4, 0, 0, 0,
+      1, // a 1byte object starting at address 4 in segment 0
+      // END TUPLES
+      0, 0, 0, 0, 0, 0, 0, 0, 0 // terminator
+  };
+  DWARFDataExtractor data;
+  data.SetData(static_cast<const void *>(binary_data), sizeof binary_data,
+               lldb::ByteOrder::eByteOrderBig);
+  DWARFDebugArangeSet debug_aranges;
+  offset_t off = 0;
+  llvm::Error error = debug_aranges.extract(data, &off);
+  EXPECT_TRUE(bool(error));
+  EXPECT_EQ("segmented arange entries are not supported",
+            llvm::toString(std::move(error)));
+  EXPECT_EQ(off, 12); // Parser should read no further than the segment size
+}


        


More information about the lldb-commits mailing list