OSDN Git Service

[BPF] Return fail if disassembled insn registers out of range
authorYonghong Song <yhs@fb.com>
Sat, 16 May 2020 05:57:25 +0000 (22:57 -0700)
committerYonghong Song <yhs@fb.com>
Tue, 19 May 2020 01:53:23 +0000 (18:53 -0700)
commit8e8f1bd75a9abd04b1f85ba92990e373fa6f5624
treeca840754f689934287cff86550e9378930513f63
parent82093e8fb7d65486ff450d33bf386aabd0d194f7
[BPF] Return fail if disassembled insn registers out of range

Daniel reported a llvm-objdump segfault like below:
  $ llvm-objdump -D bpf_xdp.o
  ...
  0000000000000000 <.strtab>:
       0:       00 63 69 6c 69 75 6d 5f <unknown>
       1:       6c 62 36 5f 61 66 66 69 w2 <<= w6
  ...
  (llvm-objdump: lib/Target/BPF/BPFGenAsmWriter.inc:1087: static const char*
   llvm::BPFInstPrinter::getRegisterName(unsigned int): Assertion
   `RegNo && RegNo < 25 && "Invalid register number!"' failed.
   Stack dump:
   0.      Program arguments: llvm-objdump -D bpf_xdp.o
    ...
    abort
    ...
    llvm::BPFInstPrinter::getRegisterName(unsigned int)
    llvm::BPFInstPrinter::printMemOperand(llvm::MCInst const*,
                          int, llvm::raw_ostream&, char const*)
    llvm::BPFInstPrinter::printInstruction(llvm::MCInst const*,
                          unsigned long, llvm::raw_ostream&)
    llvm::BPFInstPrinter::printInst(llvm::MCInst const*,
                          unsigned long, llvm::StringRef, llvm::MCSubtargetInfo const&,
                          llvm::raw_ostream&)
   ...

Basically, since -D enables disassembly for all sections, .strtab is also disassembled,
but some strings are decoded as legal instructions but with illegal register numbers.
When llvm-objdump tries to print register name for these illegal register numbers,
assertion and segfault happens.

The patch fixed the issue by returning fail for a disassembled insn if
that insn contains a reg operand with illegal reg number.
The insn will be printed as "<unknown>" instead of causing an assertion.
llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
llvm/test/CodeGen/BPF/objdump_dis_all.ll [new file with mode: 0644]