llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.59k stars 11.82k forks source link

Invalid assembly crashes LLVM assembler #73123

Open stuxnot opened 11 months ago

stuxnot commented 11 months ago

Fuzzing an assembler using LLVMs backend i found that some assembly inputs can crash the LLVM assembler (only when using intel syntax). This can be reproduced with clang version 16.0.6. One reduced example of this is the string "a a|". Using this string in inline assembly and trying to assemble the file with clang -masm=intel leads to a crash reporting:

fatal error: error in backend: SmallVector unable to grow. Requested capacity (4294967296) is larger than maximum value for size type (4294967295)

In debug.zip you can find preprocessed srcs and the run script for an example program. The associated stack dump is:

Stack dump:
0.  Program arguments: clang -c test.c -masm=intel
1.  <eof> parser at end of file
2.  Code generation
3.  Running pass 'Function Pass Manager' on module 'test.c'.
4.  Running pass 'X86 Assembly Printer' on function '@main'
 #0 0x00007f0f8861f503 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/lib/libLLVM-16.so+0xe1f503)
 #1 0x00007f0f8861c7bf llvm::sys::RunSignalHandlers() (/usr/lib/libLLVM-16.so+0xe1c7bf)
 #2 0x00007f0f88508d9a llvm::CrashRecoveryContext::HandleExit(int) (/usr/lib/libLLVM-16.so+0xd08d9a)
 #3 0x00007f0f886158d4 llvm::sys::Process::Exit(int, bool) (/usr/lib/libLLVM-16.so+0xe158d4)
 #4 0x000055f89d67f463 (/usr/bin/clang-16+0xf463)
 #5 0x00007f0f8851f002 llvm::report_fatal_error(llvm::Twine const&, bool) (/usr/lib/libLLVM-16.so+0xd1f002)
 #6 0x00007f0f8858a42b (/usr/lib/libLLVM-16.so+0xd8a42b)
 #7 0x00007f0f8858a6af llvm::SmallVectorBase<unsigned int>::grow_pod(void*, unsigned long, unsigned long) (/usr/lib/libLLVM-16.so+0xd8a6af)
 #8 0x00007f0f8c3ce806 (/usr/lib/libLLVM-16.so+0x4bce806)
 #9 0x00007f0f8c3e3c91 (/usr/lib/libLLVM-16.so+0x4be3c91)
#10 0x00007f0f8c3e86a6 (/usr/lib/libLLVM-16.so+0x4be86a6)
#11 0x00007f0f8a457951 (/usr/lib/libLLVM-16.so+0x2c57951)
#12 0x00007f0f8a476578 (/usr/lib/libLLVM-16.so+0x2c76578)
#13 0x00007f0f8a4687c0 (/usr/lib/libLLVM-16.so+0x2c687c0)
#14 0x00007f0f8919abab llvm::AsmPrinter::emitInlineAsm(llvm::StringRef, llvm::MCSubtargetInfo const&, llvm::MCTargetOptions const&, llvm::MDNode const*, llvm::InlineAsm::AsmDialect) const (/usr/lib/libLLVM-16.so+0x199abab)
#15 0x00007f0f8919b948 llvm::AsmPrinter::emitInlineAsm(llvm::MachineInstr const*) const (/usr/lib/libLLVM-16.so+0x199b948)
#16 0x00007f0f8919730b llvm::AsmPrinter::emitFunctionBody() (/usr/lib/libLLVM-16.so+0x199730b)
#17 0x00007f0f8c08a163 (/usr/lib/libLLVM-16.so+0x488a163)
#18 0x00007f0f88aea945 (/usr/lib/libLLVM-16.so+0x12ea945)
#19 0x00007f0f887ab989 llvm::FPPassManager::runOnFunction(llvm::Function&) (/usr/lib/libLLVM-16.so+0xfab989)
#20 0x00007f0f887abd34 llvm::FPPassManager::runOnModule(llvm::Module&) (/usr/lib/libLLVM-16.so+0xfabd34)
#21 0x00007f0f887ac6ac llvm::legacy::PassManagerImpl::run(llvm::Module&) (/usr/lib/libLLVM-16.so+0xfac6ac)
#22 0x00007f0f912f3fb3 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>) (/usr/lib/libclang-cpp.so.16+0x16f3fb3)
#23 0x00007f0f91619229 (/usr/lib/libclang-cpp.so.16+0x1a19229)
#24 0x00007f0f904ecfb0 clang::ParseAST(clang::Sema&, bool, bool) (/usr/lib/libclang-cpp.so.16+0x8ecfb0)
#25 0x00007f0f91d1e7c9 clang::FrontendAction::Execute() (/usr/lib/libclang-cpp.so.16+0x211e7c9)
#26 0x00007f0f91cc0d2f clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/usr/lib/libclang-cpp.so.16+0x20c0d2f)
#27 0x00007f0f91d7bf02 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/usr/lib/libclang-cpp.so.16+0x217bf02)
#28 0x000055f89d684a6f cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/usr/bin/clang-16+0x14a6f)
#29 0x000055f89d688b10 (/usr/bin/clang-16+0x18b10)
#30 0x00007f0f919ec779 (/usr/lib/libclang-cpp.so.16+0x1dec779)
#31 0x00007f0f88508c87 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/usr/lib/libLLVM-16.so+0xd08c87)
#32 0x00007f0f919f30c4 (/usr/lib/libclang-cpp.so.16+0x1df30c4)
#33 0x00007f0f91a11431 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/usr/lib/libclang-cpp.so.16+0x1e11431)
#34 0x00007f0f91a117ed clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/usr/lib/libclang-cpp.so.16+0x1e117ed)
#35 0x00007f0f91a155dc clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/usr/lib/libclang-cpp.so.16+0x1e155dc)
#36 0x000055f89d68b99f clang_main(int, char**) (/usr/bin/clang-16+0x1b99f)
#37 0x00007f0f87245cd0 (/usr/lib/libc.so.6+0x27cd0)
#38 0x00007f0f87245d8a __libc_start_main (/usr/lib/libc.so.6+0x27d8a)
#39 0x000055f89d67ced5 _start (/usr/bin/clang-16+0xced5)
clang-16: error: clang frontend command failed with exit code 70 (use -v to see invocation)
clang version 16.0.6
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

Note that without the -c flag, clang fails without producing a backtrace, but with the same error.

asl commented 11 months ago

@stuxnot Does this reproduce with the HEAD?

stuxnot commented 11 months ago

Yes, here is the generated stack dump:

fatal error: error in backend: SmallVector unable to grow. Requested capacity (4294967296) is larger than maximum value for size type (4294967295)
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.  Program arguments: bin/clang /home/stuxnot/test/test.c -masm=intel -c
1.  <eof> parser at end of file
2.  Code generation
3.  Running pass 'Function Pass Manager' on module '/home/stuxnot/test/test.c'.
4.  Running pass 'X86 Assembly Printer' on function '@main'
 #0 0x0000555c125d6f2e llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (bin/clang+0x1e9df2e)
 #1 0x0000555c125d4cac llvm::sys::CleanupOnSignal(unsigned long) (bin/clang+0x1e9bcac)
 #2 0x0000555c12516363 llvm::CrashRecoveryContext::HandleExit(int) (bin/clang+0x1ddd363)
 #3 0x0000555c125cb45e llvm::sys::Process::Exit(int, bool) (bin/clang+0x1e9245e)
 #4 0x0000555c11355504 (bin/clang+0xc1c504)
 #5 0x0000555c1251ec7f llvm::report_fatal_error(llvm::Twine const&, bool) (bin/clang+0x1de5c7f)
 #6 0x0000555c1254c65c report_size_overflow(unsigned long, unsigned long) (.constprop.0) SmallVector.cpp:0:0
 #7 0x0000555c1254c8fe llvm::SmallVectorBase<unsigned int>::grow_pod(void*, unsigned long, unsigned long) (bin/clang+0x1e138fe)
 #8 0x0000555c116e6da5 (anonymous namespace)::X86AsmParser::InfixCalculator::execute() X86AsmParser.cpp:0:0
 #9 0x0000555c116fd7e8 (anonymous namespace)::X86AsmParser::parseIntelOperand(llvm::SmallVectorImpl<std::unique_ptr<llvm::MCParsedAsmOperand, std::default_delete<llvm::MCParsedAsmOperand>>>&, llvm::StringRef) X86AsmParser.cpp:0:0
#10 0x0000555c11700d7e (anonymous namespace)::X86AsmParser::ParseInstruction(llvm::ParseInstructionInfo&, llvm::StringRef, llvm::SMLoc, llvm::SmallVectorImpl<std::unique_ptr<llvm::MCParsedAsmOperand, std::default_delete<llvm::MCParsedAsmOperand>>>&) X86AsmParser.cpp:0:0
#11 0x0000555c1236151f (anonymous namespace)::AsmParser::parseAndMatchAndEmitTargetInstruction((anonymous namespace)::ParseStatementInfo&, llvm::StringRef, llvm::AsmToken, llvm::SMLoc) AsmParser.cpp:0:0
#12 0x0000555c12381eb1 (anonymous namespace)::AsmParser::parseStatement((anonymous namespace)::ParseStatementInfo&, llvm::MCAsmParserSemaCallback*) AsmParser.cpp:0:0
#13 0x0000555c12373122 (anonymous namespace)::AsmParser::Run(bool, bool) AsmParser.cpp:0:0
#14 0x0000555c132c1853 llvm::AsmPrinter::emitInlineAsm(llvm::StringRef, llvm::MCSubtargetInfo const&, llvm::MCTargetOptions const&, llvm::MDNode const*, llvm::InlineAsm::AsmDialect) const (bin/clang+0x2b88853)
#15 0x0000555c132c276e llvm::AsmPrinter::emitInlineAsm(llvm::MachineInstr const*) const (bin/clang+0x2b8976e)
#16 0x0000555c132bdbca llvm::AsmPrinter::emitFunctionBody() (bin/clang+0x2b84bca)
#17 0x0000555c11364add llvm::X86AsmPrinter::runOnMachineFunction(llvm::MachineFunction&) (bin/clang+0xc2badd)
#18 0x0000555c11acf238 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (.part.0) MachineFunctionPass.cpp:0:0
#19 0x0000555c12081701 llvm::FPPassManager::runOnFunction(llvm::Function&) (bin/clang+0x1948701)
#20 0x0000555c12081a4c llvm::FPPassManager::runOnModule(llvm::Module&) (bin/clang+0x1948a4c)
#21 0x0000555c1208242e llvm::legacy::PassManagerImpl::run(llvm::Module&) (bin/clang+0x194942e)
#22 0x0000555c1282a1cd clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) (bin/clang+0x20f11cd)
#23 0x0000555c12defe76 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (bin/clang+0x26b6e76)
#24 0x0000555c146fd2f9 clang::ParseAST(clang::Sema&, bool, bool) (bin/clang+0x3fc42f9)
#25 0x0000555c13080659 clang::FrontendAction::Execute() (bin/clang+0x2947659)
#26 0x0000555c13002e09 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (bin/clang+0x28c9e09)
#27 0x0000555c131479cb clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (bin/clang+0x2a0e9cb)
#28 0x0000555c11356a86 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (bin/clang+0xc1da86)
#29 0x0000555c1134f23a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#30 0x0000555c12e382e9 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#31 0x0000555c12516263 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (bin/clang+0x1ddd263)
#32 0x0000555c12e386c1 clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (.part.0) Job.cpp:0:0
#33 0x0000555c12e01346 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (bin/clang+0x26c8346)
#34 0x0000555c12e01dfd clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (bin/clang+0x26c8dfd)
#35 0x0000555c12e1338c clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (bin/clang+0x26da38c)
#36 0x0000555c11354328 clang_main(int, char**, llvm::ToolContext const&) (bin/clang+0xc1b328)
#37 0x0000555c1128998f main (bin/clang+0xb5098f)
#38 0x00007f6515d58cd0 (/usr/lib/libc.so.6+0x27cd0)
#39 0x00007f6515d58d8a __libc_start_main (/usr/lib/libc.so.6+0x27d8a)
#40 0x0000555c1134e615 _start (bin/clang+0xc15615)
clang: error: clang frontend command failed with exit code 70 (use -v to see invocation)
clang version 18.0.0 (https://github.com/llvm/llvm-project cae46f6210293ba4d3568eb21b935d438934290d)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/stuxnot/llvm-project/llvm/build/bin
topperc commented 11 months ago

Asserts build fail here.

        } else {
          assert (OperandStack.size() > 1 && "Too few operands.");
          int64_t Val;
          ICToken Op2 = OperandStack.pop_back_val();
          ICToken Op1 = OperandStack.pop_back_val();