From 85a058246514673d3f92d3c15f1a0ce571854d57 Mon Sep 17 00:00:00 2001 From: Igor Kudrin Date: Fri, 14 Aug 2020 13:11:37 +0700 Subject: [PATCH] [DebugInfo] Avoid an infinite loop with a truncated pre-v5 .debug_str_offsets.dwo. dumpStringOffsetsSection() expects the size of a contribution to be correctly aligned. The patch adds the corresponding verifications for pre-v5 cases. Differential Revision: https://reviews.llvm.org/D85739 --- lib/DebugInfo/DWARF/DWARFUnit.cpp | 18 +++-- .../X86/dwarfdump-str-offsets-v4-invalid.s | 65 +++++++++++++++++++ 2 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 test/DebugInfo/X86/dwarfdump-str-offsets-v4-invalid.s diff --git a/lib/DebugInfo/DWARF/DWARFUnit.cpp b/lib/DebugInfo/DWARF/DWARFUnit.cpp index a6d44f04e46..0527f29d1a1 100644 --- a/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -995,11 +995,17 @@ DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) { // Prior to DWARF v5, we derive the contribution size from the // index table (in a package file). In a .dwo file it is simply // the length of the string offsets section. - if (!IndexEntry) - return {Optional( - {0, StringOffsetSection.Data.size(), 4, Header.getFormat()})}; + StrOffsetsContributionDescriptor Desc; if (C) - return {Optional( - {C->Offset, C->Length, 4, Header.getFormat()})}; - return None; + Desc = StrOffsetsContributionDescriptor(C->Offset, C->Length, 4, + Header.getFormat()); + else if (!IndexEntry && !StringOffsetSection.Data.empty()) + Desc = StrOffsetsContributionDescriptor(0, StringOffsetSection.Data.size(), + 4, Header.getFormat()); + else + return None; + auto DescOrError = Desc.validateContributionSize(DA); + if (!DescOrError) + return DescOrError.takeError(); + return *DescOrError; } diff --git a/test/DebugInfo/X86/dwarfdump-str-offsets-v4-invalid.s b/test/DebugInfo/X86/dwarfdump-str-offsets-v4-invalid.s new file mode 100644 index 00000000000..e8e084c9b1b --- /dev/null +++ b/test/DebugInfo/X86/dwarfdump-str-offsets-v4-invalid.s @@ -0,0 +1,65 @@ +## This tests handling invalid .debug_str_offsets.dwo sections in +## a pre-standard DWO/DWP file. + +# RUN: llvm-mc -triple x86_64 %s -filetype=obj -o %t.dwo +# RUN: not llvm-dwarfdump -v %t.dwo 2>&1 | FileCheck %s + +# RUN: llvm-mc -triple x86_64 %s -filetype=obj -o %t.dwp --defsym DWP=0 +# RUN: not llvm-dwarfdump -v %t.dwp 2>&1 | FileCheck %s + +# CHECK: error: invalid reference to or invalid content in .debug_str_offsets[.dwo]: length exceeds section size + + .section .debug_abbrev.dwo,"e",@progbits +.LAbbr: + .byte 0x01 # Abbrev code + .byte 0x11 # DW_TAG_compile_unit + .byte 0x00 # DW_CHILDREN_no + .byte 0x00 # EOM(1) + .byte 0x00 # EOM(2) + .byte 0x00 # EOM(3) +.LAbbrEnd: + + .section .debug_info.dwo,"e",@progbits +.LCU: + .long .LCUEnd-.LCUVersion +.LCUVersion: + .short 4 + .long 0 + .byte 8 + .uleb128 1 +.LCUEnd: + +## The section is truncated, i.e. its size is not a multiple of entry size. + .section .debug_str_offsets.dwo,"e",@progbits +.LStrOff: + .byte 0 +.LStrOffEnd: + +.ifdef DWP + .section .debug_cu_index, "", @progbits +## Header: + .long 2 # Version + .long 3 # Section count + .long 1 # Unit count + .long 2 # Slot count +## Hash Table of Signatures: + .quad 0x1100001122222222 # DWO Id of CU0 + .quad 0 +## Parallel Table of Indexes: + .long 1 + .long 0 +## Table of Section Offsets: +## Row 0: + .long 1 # DW_SECT_INFO + .long 3 # DW_SECT_ABBREV + .long 6 # DW_SECT_STR_OFFSETS +## Row 1, offsets of the contribution + .long .LCU-.debug_info.dwo + .long .LAbbr-.debug_abbrev.dwo + .long .LStrOff-.debug_str_offsets.dwo +## Table of Section Sizes: +## Row 1, sizes of the contribution + .long .LCUEnd-.LCU + .long .LAbbrEnd-.LAbbr + .long .LStrOffEnd-.LStrOff +.endif