tberghammer created this revision.
tberghammer added reviewers: labath, clayborg.
tberghammer added a subscriber: lldb-commits.

Fix buffer overflow for fixed_form_sizes

The array is indexed by the value in the DW_FORM filed what can be
bigger then the size of the array. This CL add bound checking to avoid
buffer overflows.

Note: This CL is part of a long series of CLs to add fission support to LLDB

http://reviews.llvm.org/D12239

Files:
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
  source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
  source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
  source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Symbol/ClangASTContext.cpp

Index: source/Symbol/ClangASTContext.cpp
===================================================================
--- source/Symbol/ClangASTContext.cpp
+++ source/Symbol/ClangASTContext.cpp
@@ -8941,7 +8941,7 @@
         case DW_TAG_template_type_parameter:
         case DW_TAG_template_value_parameter:
         {
-            const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
+            auto fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
 
             DWARFDebugInfoEntry::Attributes attributes;
             const size_t num_attributes = die->GetAttributes (dwarf,
@@ -9461,7 +9461,7 @@
 
     size_t enumerators_added = 0;
     const DWARFDebugInfoEntry *die;
-    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
+    auto fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
 
     for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
     {
@@ -9820,7 +9820,7 @@
 
     size_t count = 0;
     const DWARFDebugInfoEntry *die;
-    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
+    auto fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
     uint32_t member_idx = 0;
     BitfieldInfo last_field_info;
     ModuleSP module_sp = dwarf->GetObjectFile()->GetModule();
@@ -10402,7 +10402,7 @@
     if (parent_die == NULL)
         return 0;
 
-    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
+    auto fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
 
     size_t arg_idx = 0;
     const DWARFDebugInfoEntry *die;
@@ -10580,7 +10580,7 @@
         return;
 
     const DWARFDebugInfoEntry *die;
-    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
+    auto fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
     for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
     {
         const dw_tag_t tag = die->Tag();
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -4053,9 +4053,9 @@
                             else if (DWARFFormValue::IsDataForm(form_value.Form()))
                             {
                                 // Retrieve the value as a data expression.
-                                const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64());
+                                auto fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64());
                                 uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
-                                uint32_t data_length = fixed_form_sizes[form_value.Form()];
+                                uint32_t data_length = form_value.Form() < fixed_form_sizes->size() ? fixed_form_sizes->at(form_value.Form()) : 0;
                                 if (data_length == 0)
                                 {
                                     const uint8_t *data_pointer = form_value.BlockData();
@@ -4077,9 +4077,9 @@
                                 // Retrieve the value as a string expression.
                                 if (form_value.Form() == DW_FORM_strp)
                                 {
-                                    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64());
+                                    auto fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64());
                                     uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
-                                    uint32_t data_length = fixed_form_sizes[form_value.Form()];
+                                    uint32_t data_length = form_value.Form() < fixed_form_sizes->size() ? fixed_form_sizes->at(form_value.Form()) : 0;
                                     location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
                                 }
                                 else
Index: source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -35,6 +35,8 @@
         } value;
         const uint8_t* data;
     } ValueType;
+    
+    typedef const std::vector<uint8_t> FixedFormSizes;
 
     enum
     {
@@ -70,7 +72,7 @@
     static bool         SkipValue(const dw_form_t form, const lldb_private::DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu);
     static bool         IsBlockForm(const dw_form_t form);
     static bool         IsDataForm(const dw_form_t form);
-    static const uint8_t * GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64);
+    static FixedFormSizes* GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64);
     static int          Compare (const DWARFFormValue& a, 
                                  const DWARFFormValue& b,
                                  const lldb_private::DWARFDataExtractor* debug_str_data_ptr,
Index: source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -20,8 +20,8 @@
 using namespace lldb_private;
 
 
-static uint8_t g_form_sizes_addr4[] = 
-{
+static DWARFFormValue::FixedFormSizes
+g_form_sizes_addr4 {
     0, // 0x00 unused
     4, // 0x01 DW_FORM_addr
     0, // 0x02 unused
@@ -55,12 +55,10 @@
     0, // 0x1e
     0, // 0x1f
     8, // 0x20 DW_FORM_ref_sig8
-
 };
 
-static uint8_t
-g_form_sizes_addr8[] = 
-{
+static DWARFFormValue::FixedFormSizes
+g_form_sizes_addr8 {
     0, // 0x00 unused
     8, // 0x01 DW_FORM_addr
     0, // 0x02 unused
@@ -98,9 +96,8 @@
 
 // Difference with g_form_sizes_addr8:
 // DW_FORM_strp and DW_FORM_sec_offset are 8 instead of 4
-static uint8_t
-g_form_sizes_addr8_dwarf64[] =
-{
+static DWARFFormValue::FixedFormSizes
+g_form_sizes_addr8_dwarf64 {
     0, // 0x00 unused
     8, // 0x01 DW_FORM_addr
     0, // 0x02 unused
@@ -136,21 +133,21 @@
     8, // 0x20 DW_FORM_ref_sig8
 };
 
-const uint8_t * 
+DWARFFormValue::FixedFormSizes*
 DWARFFormValue::GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64)
 {
     if (!is_dwarf64) {
         switch (addr_size)
         {
-        case 4: return g_form_sizes_addr4;
-        case 8: return g_form_sizes_addr8;
+        case 4: return &g_form_sizes_addr4;
+        case 8: return &g_form_sizes_addr8;
         }
     } else {
         if (addr_size == 8)
-            return g_form_sizes_addr8_dwarf64;
+            return &g_form_sizes_addr8_dwarf64;
         // is_dwarf64 && addr_size == 4 : no provider does this.
     }
-    return NULL;
+    return nullptr;
 }
 
 DWARFFormValue::DWARFFormValue() :
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
@@ -88,7 +88,7 @@
 
             DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
 
-            const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (cu->GetAddressByteSize(), cu->IsDWARF64());
+            auto fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (cu->GetAddressByteSize(), cu->IsDWARF64());
 
             bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1;
 
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -144,7 +144,7 @@
     bool        FastExtract(
                     const lldb_private::DWARFDataExtractor& debug_info_data,
                     const DWARFCompileUnit* cu,
-                    const uint8_t *fixed_form_sizes,
+                    DWARFFormValue::FixedFormSizes* fixed_form_sizes,
                     lldb::offset_t* offset_ptr);
 
     bool        Extract(
@@ -162,7 +162,7 @@
     size_t      GetAttributes(
                     SymbolFileDWARF* dwarf2Data,
                     const DWARFCompileUnit* cu,
-                    const uint8_t *fixed_form_sizes,
+                    DWARFFormValue::FixedFormSizes* fixed_form_sizes,
                     DWARFDebugInfoEntry::Attributes& attrs,
                     uint32_t curr_depth = 0) const; // "curr_depth" for internal use only, don't set this yourself!!!
 
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -119,7 +119,7 @@
 (
     const DWARFDataExtractor& debug_info_data,
     const DWARFCompileUnit* cu,
-    const uint8_t *fixed_form_sizes,
+    DWARFFormValue::FixedFormSizes* fixed_form_sizes,
     lldb::offset_t *offset_ptr
 )
 {
@@ -158,7 +158,7 @@
         {
             form = abbrevDecl->GetFormByIndexUnchecked(i);
 
-            const uint8_t fixed_skip_size = fixed_form_sizes [form];
+            const uint8_t fixed_skip_size = form < fixed_form_sizes->size() ? fixed_form_sizes->at(form) : 0;
             if (fixed_skip_size)
                 offset += fixed_skip_size;
             else
@@ -1216,7 +1216,7 @@
 (
     SymbolFileDWARF* dwarf2Data,
     const DWARFCompileUnit* cu,
-    const uint8_t *fixed_form_sizes,
+    DWARFFormValue::FixedFormSizes* fixed_form_sizes,
     DWARFDebugInfoEntry::Attributes& attributes,
     uint32_t curr_depth
 ) const
@@ -1228,7 +1228,7 @@
     {
         const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
 
-        if (fixed_form_sizes == NULL)
+        if (fixed_form_sizes == nullptr)
             fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(cu->GetAddressByteSize(), cu->IsDWARF64());
 
         const uint32_t num_attributes = abbrevDecl->NumAttributes();
@@ -1283,7 +1283,7 @@
             }
             else
             {
-                const uint8_t fixed_skip_size = fixed_form_sizes [form];
+                const uint8_t fixed_skip_size = form < fixed_form_sizes->size() ? fixed_form_sizes->at(form) : 0;
                 if (fixed_skip_size)
                     offset += fixed_skip_size;
                 else
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -176,7 +176,7 @@
     die_index_stack.reserve(32);
     die_index_stack.push_back(0);
     bool prev_die_had_children = false;
-    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64);
+    auto fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64);
     while (offset < next_cu_offset &&
            die.FastExtract (debug_info_data, this, fixed_form_sizes, &offset))
     {
@@ -662,7 +662,7 @@
     const DWARFDataExtractor* debug_str = &m_dwarf2Data->get_debug_str_data();
     const DWARFDataExtractor* debug_str_offsets = &m_dwarf2Data->get_debug_str_offsets_data();
 
-    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64);
+    auto fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64);
 
     Log *log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_LOOKUPS));
     
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to