Author: tberghammer Date: Tue Aug 25 06:45:46 2015 New Revision: 245930 URL: http://llvm.org/viewvc/llvm-project?rev=245930&view=rev Log: 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 Differential revision: http://reviews.llvm.org/D12239 Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/trunk/source/Symbol/ClangASTContext.cpp Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp?rev=245930&r1=245929&r2=245930&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp Tue Aug 25 06:45:46 2015 @@ -176,7 +176,8 @@ DWARFCompileUnit::ExtractDIEsIfNeeded (b 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); + DWARFFormValue::FixedFormSizes fixed_form_sizes = + DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64); while (offset < next_cu_offset && die.FastExtract (debug_info_data, this, fixed_form_sizes, &offset)) { @@ -661,7 +662,8 @@ DWARFCompileUnit::Index (const uint32_t { const DWARFDataExtractor* debug_str = &m_dwarf2Data->get_debug_str_data(); - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64); + DWARFFormValue::FixedFormSizes fixed_form_sizes = + DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64); Log *log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_LOOKUPS)); Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp?rev=245930&r1=245929&r2=245930&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp Tue Aug 25 06:45:46 2015 @@ -119,7 +119,7 @@ DWARFDebugInfoEntry::FastExtract ( const DWARFDataExtractor& debug_info_data, const DWARFCompileUnit* cu, - const uint8_t *fixed_form_sizes, + const DWARFFormValue::FixedFormSizes& fixed_form_sizes, lldb::offset_t *offset_ptr ) { @@ -158,7 +158,7 @@ DWARFDebugInfoEntry::FastExtract { form = abbrevDecl->GetFormByIndexUnchecked(i); - const uint8_t fixed_skip_size = fixed_form_sizes [form]; + const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form); if (fixed_skip_size) offset += fixed_skip_size; else @@ -1210,7 +1210,7 @@ DWARFDebugInfoEntry::GetAttributes ( SymbolFileDWARF* dwarf2Data, const DWARFCompileUnit* cu, - const uint8_t *fixed_form_sizes, + DWARFFormValue::FixedFormSizes fixed_form_sizes, DWARFDebugInfoEntry::Attributes& attributes, uint32_t curr_depth ) const @@ -1222,8 +1222,9 @@ DWARFDebugInfoEntry::GetAttributes { const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data(); - if (fixed_form_sizes == NULL) - fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(cu->GetAddressByteSize(), cu->IsDWARF64()); + if (fixed_form_sizes.Empty()) + fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize( + cu->GetAddressByteSize(), cu->IsDWARF64()); const uint32_t num_attributes = abbrevDecl->NumAttributes(); uint32_t i; @@ -1277,7 +1278,7 @@ DWARFDebugInfoEntry::GetAttributes } else { - const uint8_t fixed_skip_size = fixed_form_sizes [form]; + const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form); if (fixed_skip_size) offset += fixed_skip_size; else @@ -1956,7 +1957,7 @@ DWARFDebugInfoEntry::GetParentDeclContex DWARFCompileUnit* cu) const { DWARFDebugInfoEntry::Attributes attributes; - GetAttributes(dwarf2Data, cu, NULL, attributes); + GetAttributes(dwarf2Data, cu, DWARFFormValue::FixedFormSizes(), attributes); return GetParentDeclContextDIE (dwarf2Data, cu, attributes); } @@ -2026,7 +2027,7 @@ DWARFDebugInfoEntry::GetQualifiedName (S std::string &storage) const { DWARFDebugInfoEntry::Attributes attributes; - GetAttributes(dwarf2Data, cu, NULL, attributes); + GetAttributes(dwarf2Data, cu, DWARFFormValue::FixedFormSizes(), attributes); return GetQualifiedName (dwarf2Data, cu, attributes, storage); } Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h?rev=245930&r1=245929&r2=245930&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h Tue Aug 25 06:45:46 2015 @@ -143,7 +143,7 @@ public: bool FastExtract( const lldb_private::DWARFDataExtractor& debug_info_data, const DWARFCompileUnit* cu, - const uint8_t *fixed_form_sizes, + const DWARFFormValue::FixedFormSizes& fixed_form_sizes, lldb::offset_t* offset_ptr); bool Extract( @@ -161,7 +161,7 @@ public: 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!!! Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp?rev=245930&r1=245929&r2=245930&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp Tue Aug 25 06:45:46 2015 @@ -87,7 +87,9 @@ DWARFDebugPubnames::GeneratePubnames(Sym DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx); - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (cu->GetAddressByteSize(), cu->IsDWARF64()); + DWARFFormValue::FixedFormSizes fixed_form_sizes = + DWARFFormValue::GetFixedFormSizesForAddressSize (cu->GetAddressByteSize(), + cu->IsDWARF64()); bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1; Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp?rev=245930&r1=245929&r2=245930&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp Tue Aug 25 06:45:46 2015 @@ -136,21 +136,21 @@ g_form_sizes_addr8_dwarf64[] = 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 FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4)); + case 8: return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8)); } } else { if (addr_size == 8) - return g_form_sizes_addr8_dwarf64; + return FixedFormSizes(g_form_sizes_addr8_dwarf64, sizeof(g_form_sizes_addr8_dwarf64)); // is_dwarf64 && addr_size == 4 : no provider does this. } - return NULL; + return FixedFormSizes(); } DWARFFormValue::DWARFFormValue() : Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h?rev=245930&r1=245929&r2=245930&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h Tue Aug 25 06:45:46 2015 @@ -35,6 +35,34 @@ public: } value; const uint8_t* data; } ValueType; + + class FixedFormSizes + { + public: + FixedFormSizes() : + m_fix_sizes(nullptr), m_size(0) + {} + + FixedFormSizes(const uint8_t* fix_sizes, size_t size) : + m_fix_sizes(fix_sizes), m_size(size) + {} + + uint8_t + GetSize(uint32_t index) const + { + return index < m_size ? m_fix_sizes[index] : 0; + } + + bool + Empty() const + { + return m_size == 0; + } + + private: + const uint8_t* m_fix_sizes; + size_t m_size; + }; enum { @@ -69,7 +97,7 @@ public: 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); protected: const DWARFCompileUnit* m_cu; // Compile unit for this form Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=245930&r1=245929&r2=245930&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Tue Aug 25 06:45:46 2015 @@ -2540,7 +2540,7 @@ SymbolFileDWARF::FunctionDieMatchesParti Mangled best_name; DWARFDebugInfoEntry::Attributes attributes; DWARFFormValue form_value; - die->GetAttributes(this, dwarf_cu, NULL, attributes); + die->GetAttributes(this, dwarf_cu, DWARFFormValue::FixedFormSizes(), attributes); uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name); if (idx == UINT32_MAX) idx = attributes.FindAttributeIndex(DW_AT_linkage_name); @@ -3990,7 +3990,10 @@ SymbolFileDWARF::ParseVariableDIE (tag == DW_TAG_formal_parameter && sc.function)) { DWARFDebugInfoEntry::Attributes attributes; - const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); + const size_t num_attributes = die->GetAttributes(this, + dwarf_cu, + DWARFFormValue::FixedFormSizes(), + attributes); if (num_attributes > 0) { const char *name = NULL; @@ -4040,9 +4043,12 @@ SymbolFileDWARF::ParseVariableDIE 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()); + DWARFFormValue::FixedFormSizes 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 = fixed_form_sizes.GetSize(form_value.Form()); if (data_length == 0) { const uint8_t *data_pointer = form_value.BlockData(); @@ -4064,9 +4070,12 @@ SymbolFileDWARF::ParseVariableDIE // 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()); + DWARFFormValue::FixedFormSizes 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 = fixed_form_sizes.GetSize(form_value.Form()); location.CopyOpcodeData(module, debug_info_data, data_offset, data_length); } else Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=245930&r1=245929&r2=245930&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Tue Aug 25 06:45:46 2015 @@ -8858,7 +8858,9 @@ ClangASTContext::ParseTemplateDIE (Symbo 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()); + DWARFFormValue::FixedFormSizes fixed_form_sizes = + DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), + dwarf_cu->IsDWARF64()); DWARFDebugInfoEntry::Attributes attributes; const size_t num_attributes = die->GetAttributes (dwarf, @@ -9399,7 +9401,9 @@ ClangASTContext::ParseChildEnumerators ( size_t enumerators_added = 0; const DWARFDebugInfoEntry *die; - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64()); + DWARFFormValue::FixedFormSizes fixed_form_sizes = + DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), + dwarf_cu->IsDWARF64()); for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) { @@ -9757,7 +9761,9 @@ ClangASTContext::ParseChildMembers (cons size_t count = 0; const DWARFDebugInfoEntry *die; - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64()); + DWARFFormValue::FixedFormSizes 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(); @@ -10333,7 +10339,9 @@ ClangASTContext::ParseChildParameters (c if (parent_die == NULL) return 0; - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64()); + DWARFFormValue::FixedFormSizes fixed_form_sizes = + DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), + dwarf_cu->IsDWARF64()); size_t arg_idx = 0; const DWARFDebugInfoEntry *die; @@ -10509,7 +10517,9 @@ ClangASTContext::ParseChildArrayInfo (co return; const DWARFDebugInfoEntry *die; - const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64()); + DWARFFormValue::FixedFormSizes 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(); @@ -10943,7 +10953,10 @@ ClangASTContext::ParseTypeFromDWARF (con // Set a bit that lets us know that we are currently parsing this dwarf->m_die_to_type[die] = DIE_IS_BEING_PARSED; - const size_t num_attributes = die->GetAttributes(dwarf, dwarf_cu, NULL, attributes); + const size_t num_attributes = die->GetAttributes(dwarf, + dwarf_cu, + DWARFFormValue::FixedFormSizes(), + attributes); uint32_t encoding = 0; lldb::user_id_t encoding_uid = LLDB_INVALID_UID; @@ -11130,7 +11143,10 @@ ClangASTContext::ParseTypeFromDWARF (con LanguageType class_language = eLanguageTypeUnknown; bool is_complete_objc_class = false; //bool struct_is_class = false; - const size_t num_attributes = die->GetAttributes(dwarf, dwarf_cu, NULL, attributes); + const size_t num_attributes = die->GetAttributes(dwarf, + dwarf_cu, + DWARFFormValue::FixedFormSizes(), + attributes); if (num_attributes > 0) { uint32_t i; @@ -11540,7 +11556,10 @@ ClangASTContext::ParseTypeFromDWARF (con lldb::user_id_t encoding_uid = DW_INVALID_OFFSET; - const size_t num_attributes = die->GetAttributes(dwarf, dwarf_cu, NULL, attributes); + const size_t num_attributes = die->GetAttributes(dwarf, + dwarf_cu, + DWARFFormValue::FixedFormSizes(), + attributes); if (num_attributes > 0) { uint32_t i; @@ -11656,7 +11675,10 @@ ClangASTContext::ParseTypeFromDWARF (con clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern - const size_t num_attributes = die->GetAttributes(dwarf, dwarf_cu, NULL, attributes); + const size_t num_attributes = die->GetAttributes(dwarf, + dwarf_cu, + DWARFFormValue::FixedFormSizes(), + attributes); if (num_attributes > 0) { uint32_t i; @@ -12125,7 +12147,10 @@ ClangASTContext::ParseTypeFromDWARF (con uint32_t byte_stride = 0; uint32_t bit_stride = 0; bool is_vector = false; - const size_t num_attributes = die->GetAttributes(dwarf, dwarf_cu, NULL, attributes); + const size_t num_attributes = die->GetAttributes(dwarf, + dwarf_cu, + DWARFFormValue::FixedFormSizes(), + attributes); if (num_attributes > 0) { @@ -12221,9 +12246,12 @@ ClangASTContext::ParseTypeFromDWARF (con { dw_offset_t type_die_offset = DW_INVALID_OFFSET; dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET; - - const size_t num_attributes = die->GetAttributes(dwarf, dwarf_cu, NULL, attributes); - + + const size_t num_attributes = die->GetAttributes(dwarf, + dwarf_cu, + DWARFFormValue::FixedFormSizes(), + attributes); + if (num_attributes > 0) { uint32_t i; for (i=0; i<num_attributes; ++i) _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits