diff options
author | Martin Storsjo <martin@martin.st> | 2017-10-24 07:16:40 +0000 |
---|---|---|
committer | Martin Storsjo <martin@martin.st> | 2017-10-24 07:16:40 +0000 |
commit | d3abd15d8cd9455bc7b1eeb2e6f4b4d0047a0dd6 (patch) | |
tree | c4571e60744ada713da45a7b681e1628606f0ff0 /libunwind/src | |
parent | 2555e41b4e933c01bb7fe651ad8520b35d9eeaca (diff) | |
download | bcm5719-llvm-d3abd15d8cd9455bc7b1eeb2e6f4b4d0047a0dd6.tar.gz bcm5719-llvm-d3abd15d8cd9455bc7b1eeb2e6f4b4d0047a0dd6.zip |
Add missing checks for register number
Most other cases that touch savedRegisters[reg] have got this check,
but these three seemed to lack it.
Differential Revision: https://reviews.llvm.org/D39206
llvm-svn: 316415
Diffstat (limited to 'libunwind/src')
-rw-r--r-- | libunwind/src/DwarfParser.hpp | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/libunwind/src/DwarfParser.hpp b/libunwind/src/DwarfParser.hpp index 3c98d304fda..d45ad49c5db 100644 --- a/libunwind/src/DwarfParser.hpp +++ b/libunwind/src/DwarfParser.hpp @@ -605,6 +605,13 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions, break; case DW_CFA_val_offset: reg = addressSpace.getULEB128(p, instructionsEnd); + if (reg > kMaxRegisterNumber) { + fprintf(stderr, + "malformed DW_CFA_val_offset DWARF unwind, reg (%" PRIu64 + ") out of range\n", + reg); + return false; + } offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor; results->savedRegisters[reg].location = kRegisterOffsetFromCFA; @@ -668,6 +675,12 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions, switch (opcode & 0xC0) { case DW_CFA_offset: reg = operand; + if (reg > kMaxRegisterNumber) { + fprintf(stderr, "malformed DW_CFA_offset DWARF unwind, reg (%" PRIu64 + ") out of range\n", + reg); + return false; + } offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor; results->savedRegisters[reg].location = kRegisterInCFA; @@ -682,6 +695,12 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions, break; case DW_CFA_restore: reg = operand; + if (reg > kMaxRegisterNumber) { + fprintf(stderr, "malformed DW_CFA_restore DWARF unwind, reg (%" PRIu64 + ") out of range\n", + reg); + return false; + } results->savedRegisters[reg] = initialState.savedRegisters[reg]; _LIBUNWIND_TRACE_DWARF("DW_CFA_restore(reg=%" PRIu64 ")\n", static_cast<uint64_t>(operand)); |