[PATCH] D80157: [BPF] Return fail if disassembled insn registers out of range
Yonghong Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon May 18 14:06:09 PDT 2020
yonghong-song created this revision.
yonghong-song added a reviewer: ast.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.
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 contain a reg operand with illegal reg number.
The insn will be printed as "<unknown>" instead of causing an assertion.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D80157
Files:
llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
llvm/test/CodeGen/BPF/objdump_dis_all.ll
Index: llvm/test/CodeGen/BPF/objdump_dis_all.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/BPF/objdump_dis_all.ll
@@ -0,0 +1,26 @@
+; RUN: llc -march=bpfel -filetype=obj -o - %s | llvm-objdump -D - | FileCheck %s
+;
+; Source:
+; /* *(u64 *)(r10 - 16) = r1 */
+; unsigned long long g = 0x00000000fff01a7bULL;
+; /* *(u64 *)(r15 - 16) = r1 */
+; unsigned long long h = 0x00000000fff01f7bULL;
+; int test() {
+; return 0;
+; }
+; Compilation flag:
+; clang -target bpf -O2 -S -emit-llvm t.c
+
+ at g = dso_local local_unnamed_addr global i64 4293925499, align 8
+ at h = dso_local local_unnamed_addr global i64 4293926779, align 8
+
+; Function Attrs: norecurse nounwind readnone
+define dso_local i32 @test() local_unnamed_addr {
+entry:
+ ret i32 0
+}
+; CHECK-LABEL: section .data
+; CHECK-LABEL: g
+; CHECK: *(u64 *)(r10 - 16) = r1
+; CHECK-LABEL: h
+; CHECK: <unknown>
Index: llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
===================================================================
--- llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
+++ llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
@@ -183,6 +183,14 @@
if (Result == MCDisassembler::Fail) return MCDisassembler::Fail;
+ /* to ensure registers in range */
+ for (unsigned i = 0, e = Instr.getNumOperands(); i != e; ++i) {
+ const MCOperand &MO = Instr.getOperand(i);
+ if (MO.isReg() &&
+ (MO.getReg() <= BPF::NoRegister || MO.getReg() >= BPF::NUM_TARGET_REGS))
+ return MCDisassembler::Fail;
+ }
+
switch (Instr.getOpcode()) {
case BPF::LD_imm64:
case BPF::LD_pseudo: {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D80157.264712.patch
Type: text/x-patch
Size: 1674 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200518/767c63ec/attachment.bin>
More information about the llvm-commits
mailing list