Issue |
145180
|
Summary |
[llvm-mc] crashes with SIGSEGV when asked to assemble certain BPF instructions with mismatched registers
|
Labels |
new issue
|
Assignees |
|
Reporter |
jcttrll
|
Due to the unusual representation of some BPF instructions in pseudo-C, the instruction register appears twice (for example, `r0` in the below code):
```
r0 = atomic_fetch_add((u64*)(r2 + 0), r0)
```
A mismatch between the two register names (for example, `r0` and `r1`), is, of course, invalid, since there is no such BPF instruction:
```
r0 = atomic_fetch_add((u64*)(r2 + 0), r1)
```
Instead of reporting a syntax error, `llvm-mc` crashes with SIGSEGV when fed such an instruction (observed in a release build of version 19.1.7):
```
$ echo 'r0 = atomic_fetch_add((u64*)(r2 + 0), r1)' | llvm-mc --arch bpf --filetype null
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0. Program arguments: llvm-mc --arch bpf --filetype null
#0 0x00007fef52043539 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/lib64/libLLVM.so.19.1+0xa43539)
#1 0x00007fef52040ac0 llvm::sys::RunSignalHandlers() (/usr/lib64/libLLVM.so.19.1+0xa40ac0)
#2 0x00007fef52043d1b SignalHandler(int) (/usr/lib64/libLLVM.so.19.1+0xa43d1b)
#3 0x00007fef50e57980 __restore_rt (/lib64/libc.so.6+0x57980)
#4 0x00007fef54c2c9b2 (anonymous namespace)::BPFAsmParser::convertToMapAndConstraints(unsigned int, llvm::SmallVectorImpl<std::unique_ptr<llvm::MCParsedAsmOperand, std::default_delete<llvm::MCParsedAsmOperand>>> const&) (/usr/lib64/libLLVM.so.19.1+0x362c9b2)
#5 0x00005559f966d750
Segmentation fault (core dumped)
```
A debug build from the GitHub `main` branch (at 0c47628515dc80bd50599f936614da07943572a4) provides more insight:
```
$ echo 'r0 = atomic_fetch_add((u64*)(r2 + 0), r1)' | ../../bin/llvm-mc --arch bpfel --filetype null
Unknown match type detected!
UNREACHABLE executed at /llvm-project/llvm/lib/Target/BPF/AsmParser/BPFAsmParser.cpp:352!
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0. Program arguments: ../../bin/llvm-mc --arch bpfel --filetype null
#0 0x00000000006bb83c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /llvm-project/llvm/lib/Support/Unix/Signals.inc:804:0
#1 0x00000000006bbcfd PrintStackTraceSignalHandler(void*) /llvm-project/llvm/lib/Support/Unix/Signals.inc:888:0
#2 0x00000000006b95e1 llvm::sys::RunSignalHandlers() /llvm-project/llvm/lib/Support/Signals.cpp:105:0
#3 0x00000000006bb1f7 SignalHandler(int, siginfo_t*, void*) /llvm-project/llvm/lib/Support/Unix/Signals.inc:418:0
#4 0x00007fbd5e257980 __restore_rt (/lib64/libc.so.6+0x57980)
#5 0x00007fbd5e2a949c __pthread_kill_implementation /usr/src/debug/glibc-2.38-150600.14.14.2.x86_64/nptl/pthread_kill.c:44:76
#6 0x00007fbd5e2578c2 gsignal /usr/src/debug/glibc-2.38-150600.14.14.2.x86_64/signal/../sysdeps/posix/raise.c:27:6
#7 0x00007fbd5e23f64f abort /usr/src/debug/glibc-2.38-150600.14.14.2.x86_64/stdlib/abort.c:81:7
#8 0x00000000006326bd bindingsErrorHandler(void*, char const*, bool) /llvm-project/llvm/lib/Support/ErrorHandling.cpp:242:0
#9 0x000000000042f672 (anonymous namespace)::BPFAsmParser::matchAndEmitInstruction(llvm::SMLoc, unsigned int&, llvm::SmallVectorImpl<std::unique_ptr<llvm::MCParsedAsmOperand, std::default_delete<llvm::MCParsedAsmOperand>>>&, llvm::MCStreamer&, unsigned long&, bool) /llvm-project/llvm/lib/Target/BPF/AsmParser/BPFAsmParser.cpp:313:0
#10 0x00000000005879d6 (anonymous namespace)::AsmParser::parseAndMatchAndEmitTargetInstruction((anonymous namespace)::ParseStatementInfo&, llvm::StringRef, llvm::AsmToken, llvm::SMLoc) /llvm-project/llvm/lib/MC/MCParser/AsmParser.cpp:2311:0
#11 0x0000000000587349 (anonymous namespace)::AsmParser::parseStatement((anonymous namespace)::ParseStatementInfo&, llvm::MCAsmParserSemaCallback*) /llvm-project/llvm/lib/MC/MCParser/AsmParser.cpp:2244:0
#12 0x00000000005815fb (anonymous namespace)::AsmParser::Run(bool, bool) /llvm-project/llvm/lib/MC/MCParser/AsmParser.cpp:979:0
#13 0x000000000040a13e AssembleInput(char const*, llvm::Target const*, llvm::SourceMgr&, llvm::MCContext&, llvm::MCStreamer&, llvm::MCAsmInfo&, llvm::MCSubtargetInfo&, llvm::MCInstrInfo&, llvm::MCTargetOptions const&) /llvm-project/llvm/tools/llvm-mc/llvm-mc.cpp:348:0
#14 0x000000000040bba7 main /llvm-project/llvm/tools/llvm-mc/llvm-mc.cpp:596:0
#15 0x00007fbd5e240eec __libc_start_call_main /usr/src/debug/glibc-2.38-150600.14.14.2.x86_64/csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#16 0x00007fbd5e240fb5 call_init /usr/src/debug/glibc-2.38-150600.14.14.2.x86_64/csu/../csu/libc-start.c:128:20
#17 0x00007fbd5e240fb5 __libc_start_main@GLIBC_2.2.5 /usr/src/debug/glibc-2.38-150600.14.14.2.x86_64/csu/../csu/libc-start.c:347:5
#18 0x00000000004097b1 _start /home/abuild/rpmbuild/BUILD/glibc-2.38/csu/../sysdeps/x86_64/start.S:117:0
Aborted (core dumped)
```
The [`switch` in `BPFAsmParser::matchAndEmitInstruction`](https://github.com/llvm/llvm-project/blob/0c47628515dc80bd50599f936614da07943572a4/llvm/lib/Target/BPF/AsmParser/BPFAsmParser.cpp#L319) is apparently missing a `case Match_InvalidTiedOperand`to handle various `Constraints` in `BPFInstrInfo.td`, such as [on line 946](https://github.com/llvm/llvm-project/blob/0c47628515dc80bd50599f936614da07943572a4/llvm/lib/Target/BPF/BPFInstrInfo.td#L946). This causes the crash when encountering the following (and possibly more) illegal instructions with mismatched registers:
```
r0 = bswap16 r1
r0 = bswap32 r1
r0 = bswap64 r1
r0 = atomic_fetch_add((u64*)(r2 + 0), r1)
r0 = atomic_fetch_and((u64*)(r2 + 0), r1)
r0 = atomic_fetch_or((u64*)(r2 + 0), r1)
r0 = atomic_fetch_xor((u64*)(r2 + 0), r1)
w0 = xchg32_32(r2 + 0, w1)
r0 = xchg_64(r2 + 0, r1)
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs