Skip to content

[Bug] Assertion failed isBasic() in wasm::Type::getBasic during atomic.cmpxchg validation #8097

@oneafter

Description

@oneafter

Description

We encountered a SIGABRT (Assertion Failure) in wasm-opt while fuzzing. The crash occurs within the wasm::FunctionValidator::visitAtomicCmpxchg logic when validating a WebAssembly binary containing atomic instructions.

The assertion isBasic() && "Basic type expected" fails inside wasm::Type::getBasic(). This suggests that the validator is attempting to treat a complex type as a Basic type while validating the operands or result of an atomic.cmpxchg instruction.

Environment

  • OS: Linux x86_64
  • Complier: Clang
  • Tools: gdb

Vulnerability Details

  • Target: wasm-opt
  • Crash Type: Assertion Failure (SIGABRT)
  • Location: src/wasm-type.h:467
  • Function: wasm::Type::getBasic() const
  • Assertion: Assertion isBasic() && "Basic type expected" failed
  • Root Cause Analysis: The stack trace shows the path: FunctionValidator::visitAtomicCmpxchg -> shouldBeIntOrUnreachable -> ValidationInfo::shouldBeIntOrUnreachable -> Type::getBasic.The validator checks if the type associated with the atomic operation is valid. It calls getBasic() without first verifying if the type isBasic(). If the input Wasm provides an invalid type for an atomic operation, the assertion fires instead of gracefully rejecting the binary.

Reproduce

gdb --args ./wasm-opt ./repro -o /dev/null
r
bt

Download Link: repro

Stack Trace (GDB)

wasm-opt: /src/binaryen/src/wasm-type.h:467: BasicType wasm::Type::getBasic() const: Assertion `isBasic() && "Basic type expected"' failed.

Thread 5 "wasm-opt" received signal SIGABRT, Aborted.
[Switching to Thread 0x7fe15c2fc6c0 (LWP 52167)]
0x00007fe160a76b2c in pthread_kill () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0  0x00007fe160a76b2c in pthread_kill () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007fe160a1d27e in raise () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007fe160a008ff in abort () from /lib/x86_64-linux-gnu/libc.so.6
#3  0x00007fe160a0081b in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4  0x00007fe160a13517 in __assert_fail () from /lib/x86_64-linux-gnu/libc.so.6
#5  0x00007fe163f90f64 in wasm::Type::getBasic (this=<optimized out>) at /src/binaryen/src/wasm-type.h:467
#6  wasm::ValidationInfo::shouldBeIntOrUnreachable (this=<optimized out>, ty=..., curr=0x52d00000bb68, func=<optimized out>, 
    text=<optimized out>) at /src/binaryen/src/wasm/wasm-validator.cpp:201
#7  wasm::FunctionValidator::shouldBeIntOrUnreachable (ty=..., curr=0x52d00000bb68, this=<optimized out>, text=<optimized out>)
    at /src/binaryen/src/wasm/wasm-validator.cpp:572
#8  wasm::FunctionValidator::visitAtomicCmpxchg (this=<optimized out>, curr=0x52d00000bb68)
    at /src/binaryen/src/wasm/wasm-validator.cpp:1213
#9  0x00007fe163fe7083 in wasm::Walker<wasm::FunctionValidator, wasm::Visitor<wasm::FunctionValidator, void> >::walk (
    this=0x5160000efdd8, root=@0x5160000027e0: 0x52d00002d828) at /src/binaryen/src/wasm-traversal.h:307
#10 0x00007fe163fe4fbd in wasm::Walker<wasm::FunctionValidator, wasm::Visitor<wasm::FunctionValidator, void> >::doWalkFunction (
    this=0x0, func=0x516000002780) at /src/binaryen/src/wasm-traversal.h:169
#11 wasm::Walker<wasm::FunctionValidator, wasm::Visitor<wasm::FunctionValidator, void> >::walkFunctionInModule (this=0x0, 
    func=0x516000002780, module=<optimized out>) at /src/binaryen/src/wasm-traversal.h:162
#12 wasm::WalkerPass<wasm::PostWalker<wasm::FunctionValidator, wasm::Visitor<wasm::FunctionValidator, void> > >::runOnFunction (
    this=0x5160000efd80, module=<optimized out>, func=0x516000002780) at /src/binaryen/src/pass.h:559
#13 0x00007fe161cf762b in wasm::PassRunner::runPassOnFunction (this=<optimized out>, pass=<optimized out>, func=<optimized out>)
    at /src/binaryen/src/passes/pass.cpp:1037
#14 0x00007fe161cfec25 in wasm::PassRunner::run()::$_0::operator()() const::{lambda()#1}::operator()() const (this=<optimized out>)
    at /src/binaryen/src/passes/pass.cpp:945
#15 std::__invoke_impl<wasm::ThreadWorkState, wasm::PassRunner::run()::$_0::operator()() const::{lambda()#1}&>(std::__invoke_other, wasm::PassRunner::run()::$_0::operator()() const::{lambda()#1}&) (__f=...)
    at /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:61
#16 std::__invoke_r<wasm::ThreadWorkState, wasm::PassRunner::run()::$_0::operator()() const::{lambda()#1}&>(wasm::PassRunner::run()::$_0::operator()() const::{lambda()#1}&) (__fn=...) at /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:114
#17 std::_Function_handler<wasm::ThreadWorkState (), wasm::PassRunner::run()::$_0::operator()() const::{lambda()#1}>::_M_invoke(std::_Any_data const&) (__functor=...) at /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_function.h:290
#18 0x00007fe163afc3b2 in std::function<wasm::ThreadWorkState ()>::operator()() const (this=<optimized out>)
    at /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_function.h:591
#19 wasm::Thread::mainLoop (self_=0x50d00000abb0) at /src/binaryen/src/support/threads.cpp:95
#20 0x00007fe160e02db4 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#21 0x000055ab9885c8eb in asan_thread_start(void*) ()
--Type <RET> for more, q to quit, c to continue without paging--
#22 0x00007fe160a74aa4 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#23 0x00007fe160b01a64 in clone () from /lib/x86_64-linux-gnu/libc.so.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions