trailofbits / vast

VAST is an experimental compiler pipeline designed for program analysis of C and C++. It provides a tower of IRs as MLIR dialects to choose the best fit representations for a program analysis or further program abstraction.
https://trailofbits.github.io/vast/
Apache License 2.0
368 stars 23 forks source link

[Bug]: `vast-front` crashes on `offsetof` anonymous nested tag fields #644

Open PappasBrent opened 5 days ago

PappasBrent commented 5 days ago

VAST version

Ubuntu clang version 18.1.8 (++20240615103753+3b5b5c1ec4a3-1~exp1~20240615223858.136) Target: x86_64-pc-linux-gnu Thread model: posix

LLVM version

18.1.8

Operating system

Ubuntu 22.04.4 LTS x86_64

Description

vast-front crashes with the following stack trace when attempting to lower a program containing an offset expression where one of its components is a field of a nested anonymous tag type:

Stack dump:
0.      Program arguments: ./builds/default/tools/vast-front/Debug/vast-front -x c -vast-emit-mlir=hl test_offsetof_anon_struct_field.c
1.      <eof> parser at end of file
 #0 0x00007f3e18e41716 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/lib/llvm-18/lib/libLLVM.so.18.1+0xd94716)
 #1 0x00007f3e18e3f6d0 llvm::sys::RunSignalHandlers() (/usr/lib/llvm-18/lib/libLLVM.so.18.1+0xd926d0)
 #2 0x00007f3e18d911f0 (/usr/lib/llvm-18/lib/libLLVM.so.18.1+0xce41f0)
 #3 0x00007f3e17b2f520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x000055aeac1a9eb0 clang::IdentifierInfo::getNameStart() const /usr/lib/llvm-18/include/clang/Basic/IdentifierTable.h:232:45
 #5 0x000055aeac1a6b79 clang::IdentifierInfo::getName() const /usr/lib/llvm-18/include/clang/Basic/IdentifierTable.h:239:22
 #6 0x000055aeac2070fc vast::cg::default_stmt_visitor::VisitOffsetOfExpr(clang::OffsetOfExpr const*) /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/DefaultStmtVisitor.cpp:951:87
 #7 0x000055aeac1afeb4 clang::StmtVisitorBase<llvm::make_const_ptr, vast::cg::default_stmt_visitor, mlir::Operation*>::Visit(clang::Stmt const*) /usr/lib/llvm-18/include/clang/AST/StmtNodes.inc:190:1
 #8 0x000055aeac1ad9fd vast::cg::default_stmt_visitor::visit(clang::Stmt const*) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/DefaultStmtVisitor.hpp:23:50
 #9 0x000055aeac1ad996 vast::cg::default_visitor::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/DefaultVisitor.cpp:20:9
#10 0x000055aeac19b2b0 auto vast::cg::try_or_through_list_node<vast::cg::default_visitor>::try_visit_or_pass<clang::Stmt const*&, vast::cg::scope_context&>(clang::Stmt const*&, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:157:22
#11 0x000055aeac19a3b5 vast::cg::try_or_through_list_node<vast::cg::default_visitor>::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:166:82
#12 0x000055aeac195e92 vast::cg::fallthrough_list_node::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:124:82
#13 0x000055aeac195e92 vast::cg::fallthrough_list_node::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:124:82
#14 0x000055aeac194f32 vast::cg::visitor_list::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:102:82
#15 0x000055aeac1a2a29 vast::cg::visitor_view::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/CodeGenVisitorBase.cpp:15:9
#16 0x000055aeac1a2b71 vast::cg::scoped_visitor_view::visit(clang::Stmt const*) /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/CodeGenVisitorBase.cpp:39:9
#17 0x000055aeac200211 mlir::Operation* vast::cg::default_stmt_visitor::visit_cast_op<vast::hl::CStyleCastOp>(clang::CastExpr const*) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/DefaultStmtVisitor.hpp:457:18
#18 0x000055aeac2001bd vast::cg::default_stmt_visitor::VisitCStyleCastExpr(clang::CStyleCastExpr const*) /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/DefaultStmtVisitor.cpp:423:9
#19 0x000055aeac1b03c6 clang::StmtVisitorBase<llvm::make_const_ptr, vast::cg::default_stmt_visitor, mlir::Operation*>::Visit(clang::Stmt const*) /usr/lib/llvm-18/include/clang/AST/StmtNodes.inc:576:1
#20 0x000055aeac1ad9fd vast::cg::default_stmt_visitor::visit(clang::Stmt const*) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/DefaultStmtVisitor.hpp:23:50
#21 0x000055aeac1ad996 vast::cg::default_visitor::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/DefaultVisitor.cpp:20:9
#22 0x000055aeac19b2b0 auto vast::cg::try_or_through_list_node<vast::cg::default_visitor>::try_visit_or_pass<clang::Stmt const*&, vast::cg::scope_context&>(clang::Stmt const*&, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:157:22
#23 0x000055aeac19a3b5 vast::cg::try_or_through_list_node<vast::cg::default_visitor>::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:166:82
#24 0x000055aeac195e92 vast::cg::fallthrough_list_node::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:124:82
#25 0x000055aeac195e92 vast::cg::fallthrough_list_node::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:124:82
#26 0x000055aeac194f32 vast::cg::visitor_list::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:102:82
#27 0x000055aeac1a2a29 vast::cg::visitor_view::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/CodeGenVisitorBase.cpp:15:9
#28 0x000055aeac1a2b71 vast::cg::scoped_visitor_view::visit(clang::Stmt const*) /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/CodeGenVisitorBase.cpp:39:9
#29 0x000055aeac24c804 vast::cg::block_generator::emit(clang::CompoundStmt const*) /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/CodeGenBlock.cpp:19:21
#30 0x000055aeac1fa52e vast::cg::default_stmt_visitor::VisitCompoundStmt(clang::CompoundStmt const*) /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/DefaultStmtVisitor.cpp:102:9
#31 0x000055aeac1b0ffa clang::StmtVisitorBase<llvm::make_const_ptr, vast::cg::default_stmt_visitor, mlir::Operation*>::Visit(clang::Stmt const*) /usr/lib/llvm-18/include/clang/AST/StmtNodes.inc:1498:1
#32 0x000055aeac1ad9fd vast::cg::default_stmt_visitor::visit(clang::Stmt const*) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/DefaultStmtVisitor.hpp:23:50
#33 0x000055aeac1ad996 vast::cg::default_visitor::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/DefaultVisitor.cpp:20:9
#34 0x000055aeac19b2b0 auto vast::cg::try_or_through_list_node<vast::cg::default_visitor>::try_visit_or_pass<clang::Stmt const*&, vast::cg::scope_context&>(clang::Stmt const*&, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:157:22
#35 0x000055aeac19a3b5 vast::cg::try_or_through_list_node<vast::cg::default_visitor>::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:166:82
#36 0x000055aeac195e92 vast::cg::fallthrough_list_node::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:124:82
#37 0x000055aeac195e92 vast::cg::fallthrough_list_node::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:124:82
#38 0x000055aeac194f32 vast::cg::visitor_list::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/CodeGenVisitorList.hpp:102:82
#39 0x000055aeac1a2a29 vast::cg::visitor_view::visit(clang::Stmt const*, vast::cg::scope_context&) /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/CodeGenVisitorBase.cpp:15:9
#40 0x000055aeac1a2b71 vast::cg::scoped_visitor_view::visit(clang::Stmt const*) /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/CodeGenVisitorBase.cpp:39:9
#41 0x000055aeac1f1b4c vast::cg::function_generator::emit_body(clang::FunctionDecl const*, vast::hl::FuncOp) /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/CodeGenFunction.cpp:128:21
#42 0x000055aeac1f53d2 vast::cg::function_generator::emit(clang::FunctionDecl const*)::$_0::operator()() /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/CodeGenFunction.cpp:89:21
#43 0x000055aeac1f5315 void std::__invoke_impl<void, vast::cg::function_generator::emit(clang::FunctionDecl const*)::$_0&>(std::__invoke_other, vast::cg::function_generator::emit(clang::FunctionDecl const*)::$_0&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:61:7
#44 0x000055aeac1f52d5 std::enable_if<is_invocable_r_v<void, vast::cg::function_generator::emit(clang::FunctionDecl const*)::$_0&>, void>::type std::__invoke_r<void, vast::cg::function_generator::emit(clang::FunctionDecl const*)::$_0&>(vast::cg::function_generator::emit(clang::FunctionDecl const*)::$_0&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:117:5
#45 0x000055aeac1f51ad std::_Function_handler<void (), vast::cg::function_generator::emit(clang::FunctionDecl const*)::$_0>::_M_invoke(std::_Any_data const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_function.h:290:2
#46 0x000055aeac18f235 std::function<void ()>::operator()() const /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_function.h:591:2
#47 0x000055aeac18f0c5 vast::cg::scope_context::finalize() /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/ScopeContext.hpp:143:17
#48 0x000055aeac18f115 vast::cg::scope_context::finalize() /home/bpappas/github.com/trailofbits/vast/include/vast/CodeGen/ScopeContext.hpp:148:34
#49 0x000055aeac1a276d vast::cg::module_generator::finalize() /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/CodeGenModule.cpp:26:61
#50 0x000055aeac1859a0 vast::cg::driver::finalize() /home/bpappas/github.com/trailofbits/vast/lib/vast/CodeGen/CodeGenDriver.cpp:70:19
#51 0x000055aeac17d166 vast::cc::vast_consumer::HandleTranslationUnit(clang::ASTContext&) /home/bpappas/github.com/trailofbits/vast/lib/vast/Frontend/Consumer.cpp:67:5
#52 0x000055aeac17d9e7 vast::cc::vast_stream_consumer::HandleTranslationUnit(clang::ASTContext&) /home/bpappas/github.com/trailofbits/vast/lib/vast/Frontend/Consumer.cpp:125:15
#53 0x00007f3e2025bfc6 clang::ParseAST(clang::Sema&, bool, bool) (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0xb7ffc6)
#54 0x000055aeabd53e05 vast::cc::vast_stream_action::ExecuteAction() /home/bpappas/github.com/trailofbits/vast/lib/vast/Frontend/Action.cpp:75:5
#55 0x00007f3e2208cab5 clang::FrontendAction::Execute() (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0x29b0ab5)
#56 0x00007f3e22006084 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0x292a084)
#57 0x000055aeabd3bd17 vast::cc::execute_compiler_invocation(clang::CompilerInstance*, vast::cc::vast_args const&) /home/bpappas/github.com/trailofbits/vast/tools/vast-front/compiler_invocation.cpp:101:28
#58 0x000055aeabd50410 vast::cc::cc1(vast::cc::vast_args const&, llvm::ArrayRef<char const*>, char const*, void*) /home/bpappas/github.com/trailofbits/vast/tools/vast-front/cc1.cpp:116:23
#59 0x000055aeabd41444 execute_cc1_tool(llvm::SmallVectorImpl<char const*>&) /home/bpappas/github.com/trailofbits/vast/tools/vast-front/driver.cpp:71:16
#60 0x000055aeabd4c41d int llvm::function_ref<int (llvm::SmallVectorImpl<char const*>&)>::callback_fn<int (*)(llvm::SmallVectorImpl<char const*>&)>(long, llvm::SmallVectorImpl<char const*>&) /usr/lib/llvm-18/include/llvm/ADT/STLFunctionalExtras.h:45:5
#61 0x00007f3e21cbe5c9 (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0x25e25c9)
#62 0x00007f3e18d90f8c llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/usr/lib/llvm-18/lib/libLLVM.so.18.1+0xce3f8c)
#63 0x00007f3e21cbdf5e clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0x25e1f5e)
#64 0x00007f3e21c864d1 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0x25aa4d1)
#65 0x00007f3e21c8671e clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0x25aa71e)
#66 0x00007f3e21ca2d2d clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/usr/lib/llvm-18/lib/libclang-cpp.so.18.1+0x25c6d2d)
#67 0x000055aeabd41ada vast::cc::driver::execute() /home/bpappas/github.com/trailofbits/vast/include/vast/Frontend/Driver.hpp:180:30
#68 0x000055aeabd40ad8 main /home/bpappas/github.com/trailofbits/vast/tools/vast-front/driver.cpp:161:19
#69 0x00007f3e17b16d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#70 0x00007f3e17b16e40 call_init ./csu/../csu/libc-start.c:128:20
#71 0x00007f3e17b16e40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#72 0x000055aeabd3a715 _start (./builds/default/tools/vast-front/Debug/vast-front+0xe49715)
vast-front: error: clang frontend command failed with exit code 139 (use -v to see invocation)
Ubuntu clang version 18.1.8 (++20240615103753+3b5b5c1ec4a3-1~exp1~20240615223858.136)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /home/bpappas/github.com/trailofbits/vast/./builds/default/tools/vast-front/Debug
vast-front: error: unable to execute command: Segmentation fault (core dumped)
vast-front: note: diagnostic msg: Error generating preprocessed source(s).

Steps to Reproduce

Create a file test_offsetof_anon_struct_field.c with the following contents:

struct foo {
    struct {
        int bar;
    };
};

int main(void) {
    (void) __builtin_offsetof(struct foo, bar);
    return 0;
}

Run vast-front on the file like so:

vast-front -x c -vast-emit-mlir=hl test.c
PappasBrent commented 5 days ago

A solution to this problem will need to handle arbitrarily nested anonymous tag types, e.g., this should be fine as well:

struct foo {
    struct {
        union {
            struct {
                int bar;
            };
        };
    };
};

int main(void) {
    (void) __builtin_offsetof(struct foo, bar);
    return 0;
}