[llvm] e8bcf4e - [DebugInfo] Add use of truncating data extractor to debug line parsing
James Henderson via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 1 04:34:08 PDT 2020
Author: James Henderson
Date: 2020-06-01T12:33:21+01:00
New Revision: e8bcf4ef07ccba4a707b197f1bdee05a19936c47
URL: https://github.com/llvm/llvm-project/commit/e8bcf4ef07ccba4a707b197f1bdee05a19936c47
DIFF: https://github.com/llvm/llvm-project/commit/e8bcf4ef07ccba4a707b197f1bdee05a19936c47.diff
LOG: [DebugInfo] Add use of truncating data extractor to debug line parsing
This will ensure that nothing can ever start parsing data from a future
sequence and part-read data will be returned as 0 instead.
Reviewed by: aprantl, labath
Differential Revision: https://reviews.llvm.org/D80796
Added:
Modified:
llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_line_malformed.s
llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test
Removed:
################################################################################
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index ce59d731ac58..b2d368c096cc 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -721,14 +721,17 @@ Error DWARFDebugLine::LineTable::parse(
ProgramLength = BytesRemaining;
}
+ // Create a DataExtractor which can only see the data up to the end of the
+ // table, to prevent reading past the end.
const uint64_t EndOffset = DebugLineOffset + ProgramLength;
+ DWARFDataExtractor TableData(DebugLineData, EndOffset);
// See if we should tell the data extractor the address size.
- if (DebugLineData.getAddressSize() == 0)
- DebugLineData.setAddressSize(Prologue.getAddressSize());
+ if (TableData.getAddressSize() == 0)
+ TableData.setAddressSize(Prologue.getAddressSize());
else
assert(Prologue.getAddressSize() == 0 ||
- Prologue.getAddressSize() == DebugLineData.getAddressSize());
+ Prologue.getAddressSize() == TableData.getAddressSize());
ParsingState State(this, DebugLineOffset, RecoverableErrorHandler);
@@ -738,7 +741,7 @@ Error DWARFDebugLine::LineTable::parse(
*OS << format("0x%08.08" PRIx64 ": ", *OffsetPtr);
uint64_t OpcodeOffset = *OffsetPtr;
- uint8_t Opcode = DebugLineData.getU8(OffsetPtr);
+ uint8_t Opcode = TableData.getU8(OffsetPtr);
if (OS)
*OS << format("%02.02" PRIx8 " ", Opcode);
@@ -746,7 +749,7 @@ Error DWARFDebugLine::LineTable::parse(
if (Opcode == 0) {
// Extended Opcodes always start with a zero opcode followed by
// a uleb128 length so you can skip ones you don't know about
- uint64_t Len = DebugLineData.getULEB128(OffsetPtr);
+ uint64_t Len = TableData.getULEB128(OffsetPtr);
uint64_t ExtOffset = *OffsetPtr;
// Tolerate zero-length; assume length is correct and soldier on.
@@ -756,7 +759,7 @@ Error DWARFDebugLine::LineTable::parse(
continue;
}
- uint8_t SubOpcode = DebugLineData.getU8(OffsetPtr);
+ uint8_t SubOpcode = TableData.getU8(OffsetPtr);
if (OS)
*OS << LNExtendedString(SubOpcode);
switch (SubOpcode) {
@@ -789,7 +792,7 @@ Error DWARFDebugLine::LineTable::parse(
// Make sure the extractor knows the address size. If not, infer it
// from the size of the operand.
{
- uint8_t ExtractorAddressSize = DebugLineData.getAddressSize();
+ uint8_t ExtractorAddressSize = TableData.getAddressSize();
uint64_t OpcodeAddressSize = Len - 1;
if (ExtractorAddressSize != OpcodeAddressSize &&
ExtractorAddressSize != 0)
@@ -812,13 +815,13 @@ Error DWARFDebugLine::LineTable::parse(
OpcodeAddressSize, ExtOffset));
*OffsetPtr += OpcodeAddressSize;
} else {
- DebugLineData.setAddressSize(OpcodeAddressSize);
- State.Row.Address.Address = DebugLineData.getRelocatedAddress(
+ TableData.setAddressSize(OpcodeAddressSize);
+ State.Row.Address.Address = TableData.getRelocatedAddress(
OffsetPtr, &State.Row.Address.SectionIndex);
// Restore the address size if the extractor already had it.
if (ExtractorAddressSize != 0)
- DebugLineData.setAddressSize(ExtractorAddressSize);
+ TableData.setAddressSize(ExtractorAddressSize);
}
if (OS)
@@ -849,12 +852,12 @@ Error DWARFDebugLine::LineTable::parse(
// the file register of the state machine.
{
FileNameEntry FileEntry;
- const char *Name = DebugLineData.getCStr(OffsetPtr);
+ const char *Name = TableData.getCStr(OffsetPtr);
FileEntry.Name =
DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, Name);
- FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr);
- FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr);
- FileEntry.Length = DebugLineData.getULEB128(OffsetPtr);
+ FileEntry.DirIdx = TableData.getULEB128(OffsetPtr);
+ FileEntry.ModTime = TableData.getULEB128(OffsetPtr);
+ FileEntry.Length = TableData.getULEB128(OffsetPtr);
Prologue.FileNames.push_back(FileEntry);
if (OS)
*OS << " (" << Name << ", dir=" << FileEntry.DirIdx << ", mod_time="
@@ -864,7 +867,7 @@ Error DWARFDebugLine::LineTable::parse(
break;
case DW_LNE_set_discriminator:
- State.Row.Discriminator = DebugLineData.getULEB128(OffsetPtr);
+ State.Row.Discriminator = TableData.getULEB128(OffsetPtr);
if (OS)
*OS << " (" << State.Row.Discriminator << ")";
break;
@@ -913,7 +916,7 @@ Error DWARFDebugLine::LineTable::parse(
// result to the address register of the state machine.
{
uint64_t AddrOffset = State.advanceAddr(
- DebugLineData.getULEB128(OffsetPtr), Opcode, OpcodeOffset);
+ TableData.getULEB128(OffsetPtr), Opcode, OpcodeOffset);
if (OS)
*OS << " (" << AddrOffset << ")";
}
@@ -922,7 +925,7 @@ Error DWARFDebugLine::LineTable::parse(
case DW_LNS_advance_line:
// Takes a single signed LEB128 operand and adds that value to
// the line register of the state machine.
- State.Row.Line += DebugLineData.getSLEB128(OffsetPtr);
+ State.Row.Line += TableData.getSLEB128(OffsetPtr);
if (OS)
*OS << " (" << State.Row.Line << ")";
break;
@@ -930,7 +933,7 @@ Error DWARFDebugLine::LineTable::parse(
case DW_LNS_set_file:
// Takes a single unsigned LEB128 operand and stores it in the file
// register of the state machine.
- State.Row.File = DebugLineData.getULEB128(OffsetPtr);
+ State.Row.File = TableData.getULEB128(OffsetPtr);
if (OS)
*OS << " (" << State.Row.File << ")";
break;
@@ -938,7 +941,7 @@ Error DWARFDebugLine::LineTable::parse(
case DW_LNS_set_column:
// Takes a single unsigned LEB128 operand and stores it in the
// column register of the state machine.
- State.Row.Column = DebugLineData.getULEB128(OffsetPtr);
+ State.Row.Column = TableData.getULEB128(OffsetPtr);
if (OS)
*OS << " (" << State.Row.Column << ")";
break;
@@ -986,7 +989,7 @@ Error DWARFDebugLine::LineTable::parse(
// requires the use of DW_LNS_advance_pc. Such assemblers, however,
// can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
{
- uint16_t PCOffset = DebugLineData.getRelocatedValue(2, OffsetPtr);
+ uint16_t PCOffset = TableData.getRelocatedValue(2, OffsetPtr);
State.Row.Address.Address += PCOffset;
if (OS)
*OS
@@ -1009,7 +1012,7 @@ Error DWARFDebugLine::LineTable::parse(
case DW_LNS_set_isa:
// Takes a single unsigned LEB128 operand and stores it in the
// column register of the state machine.
- State.Row.Isa = DebugLineData.getULEB128(OffsetPtr);
+ State.Row.Isa = TableData.getULEB128(OffsetPtr);
if (OS)
*OS << " (" << (uint64_t)State.Row.Isa << ")";
break;
@@ -1022,7 +1025,7 @@ Error DWARFDebugLine::LineTable::parse(
assert(Opcode - 1U < Prologue.StandardOpcodeLengths.size());
uint8_t OpcodeLength = Prologue.StandardOpcodeLengths[Opcode - 1];
for (uint8_t I = 0; I < OpcodeLength; ++I) {
- uint64_t Value = DebugLineData.getULEB128(OffsetPtr);
+ uint64_t Value = TableData.getULEB128(OffsetPtr);
if (OS)
*OS << format("Skipping ULEB128 value: 0x%16.16" PRIx64 ")\n",
Value);
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_line_malformed.s b/llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_line_malformed.s
index d8809d11daab..9a40b5674575 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_line_malformed.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_line_malformed.s
@@ -488,6 +488,36 @@
.byte 0, 1, 1 # DW_LNE_end_sequence
.Lunterminated_files_end:
+# Opcode extends past the end of the table, as claimed by the unit length field.
+.long .Lextended_past_end_end - .Lextended_past_end_start # Length of Unit
+.Lextended_past_end_start:
+.short 4 # DWARF version number
+.long .Lprologue_extended_past_end_end-.Lprologue_extended_past_end_start # Length of Prologue
+.Lprologue_extended_past_end_start:
+.byte 1 # Minimum Instruction Length
+.byte 1 # Maximum Operations per Instruction
+.byte 1 # Default is_stmt
+.byte -5 # Line Base
+.byte 14 # Line Range
+.byte 13 # Opcode Base
+.byte 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 # Standard Opcode Lengths
+.asciz "dir1" # Include table
+.asciz "dir2"
+.byte 0
+.asciz "file1" # File table
+.byte 0, 0, 0
+.asciz "file2"
+.byte 1, 0, 0
+.byte 0
+.Lprologue_extended_past_end_end:
+.byte 0, 9, 2 # DW_LNE_set_address
+.quad 0xfeedfeed
+.byte 1 # DW_LNS_copy
+.byte 0, 9, 2 # DW_LNE_set_address
+.long 0xf001f000 # Truncated address (should be 8 bytes)
+.byte 0xf0, 0, 1
+.Lextended_past_end_end:
+
# Trailing good section.
.long .Lunit_good_end - .Lunit_good_start # Length of Unit (DWARF-32 format)
.Lunit_good_start:
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test
index 5386ef9b93a6..5c9f6edf014c 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test
@@ -33,7 +33,7 @@
# RUN: FileCheck %s --input-file=%t-malformed-off-first.err --check-prefix=ALL
## Don't stop looking for the later unit if non-fatal issues are found.
-# RUN: llvm-dwarfdump -debug-line=0x3c9 %t-malformed.o 2> %t-malformed-off-last.err \
+# RUN: llvm-dwarfdump -debug-line=0x419 %t-malformed.o 2> %t-malformed-off-last.err \
# RUN: | FileCheck %s --check-prefix=LAST --implicit-check-not='debug_line[{{.*}}]'
# RUN: FileCheck %s --input-file=%t-malformed-off-last.err --check-prefix=ALL
@@ -243,7 +243,14 @@
# VERBOSE: DW_LNE_set_address (0xababcdcdefef0909)
# VERBOSE-NEXT: DW_LNE_end_sequence
-# LAST: debug_line[0x000003c9]
+## Table with extended opcode that overruns table end.
+# NONFATAL: debug_line[0x000003c9]
+# NONFATAL-NEXT: Line table prologue
+# VERBOSE: DW_LNE_set_address (0x00000000feedfeed)
+# VERBOSE-NEXT: DW_LNS_copy
+# VERBOSE: DW_LNE_set_address (0x0000000000000000)
+
+# LAST: debug_line[0x00000419]
# VERBOSE: DW_LNE_set_address (0x00000000cafebabe)
# VERBOSE-NEXT: DW_LNE_end_sequence
@@ -272,4 +279,6 @@
# ALL-NEXT: warning: include directories table was not null terminated before the end of the prologue
# ALL-NEXT: warning: parsing line table prologue at 0x00000390 found an invalid directory or file table description at 0x000003bf
# ALL-NEXT: warning: file names table was not null terminated before the end of the prologue
+# OTHER-NEXT: warning: unexpected line op length at offset 0x00000411 expected 0x09 found 0x01
+# OTHER-NEXT: warning: last sequence in debug line table at offset 0x000003c9 is not terminated
# ALL-NOT: warning:
More information about the llvm-commits
mailing list