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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits