Skip to content

Conversation

@clonker
Copy link
Member

@clonker clonker commented Oct 22, 2025

Records linker symbols in the evm instruction interpreter instead of failing with an unknown builtin assert. The record serves as reflection of the symbolic state of the program and can eg be used for linking down the line.

Should fix the fuzzer error:

boost::wrapexcept<solidity::yul::YulAssertion>: Unknown builtin: linkersymbol
==134877== ERROR: libFuzzer: deadly signal
    #0 0x55dd88e652d4 in __sanitizer_print_stack_trace /src/llvm-project/compiler-rt/lib/ubsan/ubsan_diag_standalone.cpp:31:3
    #1 0x55dd88de4318 in fuzzer::PrintStackTrace() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerUtil.cpp:210:5
    #2 0x55dd88dc76b3 in fuzzer::Fuzzer::CrashCallback() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:231:3
    #3 0x7f51d182541f  (/lib/x86_64-linux-gnu/libpthread.so.0+0x1441f) (BuildId: 9a65bb469e45a1c6fbcffae5b82a2fd7a69eb479)
    #4 0x7f51d14ca00a in raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300a) (BuildId: 0702430aef5fa3dda43986563e9ffcc47efbd75e)
    #5 0x7f51d14a9858 in abort (/lib/x86_64-linux-gnu/libc.so.6+0x22858) (BuildId: 0702430aef5fa3dda43986563e9ffcc47efbd75e)
    #6 0x55dd89831df5 in abort_message crtstuff.c
    #7 0x55dd8988e04a in demangling_terminate_handler() cxa_default_handlers.cpp
    #8 0x55dd89831952 in std::__terminate(void (*)()) crtstuff.c
    #9 0x55dd89833985 in __cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*) cxa_exception.cpp
    #10 0x55dd8983396f in __cxa_throw (/root/project/build/test/tools/ossfuzz/strictasm_diff_ossfuzz+0x178996f)
    #11 0x55dd88e692de in void boost::throw_exception<solidity::yul::YulAssertion>(solidity::yul::YulAssertion const&) /usr/include/boost/throw_exception.hpp:165:5
    #12 0x55dd88ec9de4 in solidity::yul::test::EVMInstructionInterpreter::evalBuiltin(solidity::yul::BuiltinFunctionForEVM const&, std::__1::vector<std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal>, std::__1::allocator<std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal>>> const&, std::__1::vector<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::allocator<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>>> const&) /root/project/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp:554:3
    #13 0x55dd88e929c6 in solidity::yul::test::ExpressionEvaluator::operator()(solidity::yul::FunctionCall const&) /root/project/test/tools/yulInterpreter/Interpreter.cpp:322:35
    #14 0x55dd89151a5d in __visit_alt<std::__1::__variant_detail::__visitation::__variant::__value_visitor<solidity::yul::ASTWalker &>, const std::__1::__variant_detail::__impl<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal> &> /usr/local/bin/../include/c++/v1/variant:501:12
    #15 0x55dd89151a5d in __visit_alt<std::__1::__variant_detail::__visitation::__variant::__value_visitor<solidity::yul::ASTWalker &>, const std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal> &> /usr/local/bin/../include/c++/v1/variant:586:12
    #16 0x55dd89151a5d in __visit_value<solidity::yul::ASTWalker &, const std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal> &> /usr/local/bin/../include/c++/v1/variant:598:12
    #17 0x55dd89151a5d in visit<solidity::yul::ASTWalker &, const std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal> &, void> /usr/local/bin/../include/c++/v1/variant:1561:10
    #18 0x55dd89151a5d in solidity::yul::ASTWalker::visit(std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal> const&) /root/project/libyul/optimiser/ASTWalker.cpp:98:2
    #19 0x55dd88e90972 in solidity::yul::test::Interpreter::evaluateMulti(std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal> const&) /root/project/test/tools/yulInterpreter/Interpreter.cpp:261:5
    #20 0x55dd88e8ab7f in solidity::yul::test::Interpreter::operator()(solidity::yul::VariableDeclaration const&) /root/project/test/tools/yulInterpreter/Interpreter.cpp:143:12
    #21 0x55dd891518c8 in __visit_alt<std::__1::__variant_detail::__visitation::__variant::__value_visitor<solidity::yul::ASTWalker &>, const std::__1::__variant_detail::__impl<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> &> /usr/local/bin/../include/c++/v1/variant:501:12
    #22 0x55dd891518c8 in __visit_alt<std::__1::__variant_detail::__visitation::__variant::__value_visitor<solidity::yul::ASTWalker &>, const std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> &> /usr/local/bin/../include/c++/v1/variant:586:12
    #23 0x55dd891518c8 in __visit_value<solidity::yul::ASTWalker &, const std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> &> /usr/local/bin/../include/c++/v1/variant:598:12
    #24 0x55dd891518c8 in visit<solidity::yul::ASTWalker &, const std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> &, void> /usr/local/bin/../include/c++/v1/variant:1561:10
    #25 0x55dd891518c8 in solidity::yul::ASTWalker::visit(std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const&) /root/project/libyul/optimiser/ASTWalker.cpp:93:2
    #26 0x55dd88e892f3 in solidity::yul::test::Interpreter::operator()(solidity::yul::Block const&) /root/project/test/tools/yulInterpreter/Interpreter.cpp:243:3
    #27 0x55dd88e88b9a in solidity::yul::test::Interpreter::run(solidity::yul::test::InterpreterState&, solidity::yul::AST const&, bool, bool) /root/project/test/tools/yulInterpreter/Interpreter.cpp:118:2
    #28 0x55dd88e801a6 in solidity::yul::test::yul_fuzzer::yulFuzzerUtil::interpret(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, solidity::yul::AST const&, bool, bool, unsigned long, unsigned long, unsigned long) /root/project/test/tools/ossfuzz/yulFuzzerCommon.cpp:54:3
    #29 0x55dd88e66fad in LLVMFuzzerTestOneInput /root/project/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp:91:48
    #30 0x55dd88dc8bc0 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:614:13
    #31 0x55dd88db3e35 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:327:6
    #32 0x55dd88db98cf in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:862:9
    #33 0x55dd88de4b72 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #34 0x7f51d14ab082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 0702430aef5fa3dda43986563e9ffcc47efbd75e)
    #35 0x55dd88dac01d in _start (/root/project/build/test/tools/ossfuzz/strictasm_diff_ossfuzz+0xd0201d)

NOTE: libFuzzer has rudimentary signal handlers.
      Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal

bool m_disableMemoryWriteInstructions;
/// mapping from linker identifier (hash of literal) to original string representation, populated by linkersymbol
/// calls
std::map<util::h256, std::string> m_linkerSymbols;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this read from anywhere?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope for now it's just the symbolic state of the interpreter

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this fix the bug? I.e. how does the fuzzer now become aware that this value is part of the state?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't a bug per se. The fuzzer interprets through evm instructions and upon invoking linkersymbol it ran into the unknown builtin assert as you can see in the pasted message of the PR description. Since the linkersymbol is something that is evaluated and dealt with at link time, there's nothing to do really beyond not letting the fuzzer fail. Alternatively I could have just let it be a real no-op and not record anything but decided against YAGNI and added the map since I thought we might need it anyways - in particular when fuzzing deployed bytecode with calldata.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, of course.

Copy link
Collaborator

@blishko blishko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGMT!

@clonker clonker merged commit 6156813 into develop Oct 22, 2025
77 checks passed
@clonker clonker deleted the record_linker_symbols branch October 22, 2025 09:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants