Skip to content

[Segmentation fault] Out-of-bounds read in wasm::HeapType::isBasic #6848

@sofiaaberegg

Description

@sofiaaberegg

Hi,

I identified an out-of-bounds data read bug when fuzzing the wasm-opt tool.

Steps to reproduce:

Test file: wast-oob-read.zip
Command: ./wasm-opt ./wast-oob-read.wast

GDB:

gdb --args ./wasm-opt ./wast-oob-read.wast 
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.2) 12.1

Reading symbols from ./wasm-opt...
(gdb) run
Starting program: /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/bin/wasm-opt ./wast-oob-read.wast
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff7600640 (LWP 907262)]
[New Thread 0x7ffff6c00640 (LWP 907263)]
[New Thread 0x7ffff6200640 (LWP 907264)]
[New Thread 0x7ffff5800640 (LWP 907265)]
[New Thread 0x7ffff4e00640 (LWP 907266)]
[New Thread 0x7ffff4400640 (LWP 907267)]
[New Thread 0x7ffff3a00640 (LWP 907268)]
[New Thread 0x7ffff3000640 (LWP 907269)]
[New Thread 0x7ffff2600640 (LWP 907270)]
[New Thread 0x7ffff1c00640 (LWP 907271)]
[New Thread 0x7ffff1200640 (LWP 907272)]
[New Thread 0x7ffff0800640 (LWP 907273)]
[New Thread 0x7fffefe00640 (LWP 907274)]
[New Thread 0x7fffef400640 (LWP 907275)]
[New Thread 0x7fffeea00640 (LWP 907276)]
[New Thread 0x7fffee000640 (LWP 907277)]
[New Thread 0x7fffed600640 (LWP 907278)]
[New Thread 0x7fffecc00640 (LWP 907279)]
[New Thread 0x7fffec200640 (LWP 907280)]
[New Thread 0x7fffeb800640 (LWP 907281)]
[New Thread 0x7fffeae00640 (LWP 907282)]
[New Thread 0x7fffea400640 (LWP 907283)]
[New Thread 0x7fffe9a00640 (LWP 907284)]
[New Thread 0x7fffe9000640 (LWP 907285)]

Thread 1 "wasm-opt" received signal SIGSEGV, Segmentation fault.
0x00005555555b80b2 in wasm::HeapType::isBasic (this=0x38) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm-type.h:378
378	  constexpr bool isBasic() const { return id <= _last_basic_type; }
(gdb) bt
#0  0x00005555555b80b2 in wasm::HeapType::isBasic (this=0x38) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm-type.h:378
#1  0x000055555616e814 in wasm::HeapType::getKind (this=0x38) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm/wasm-type.cpp:1100
#2  0x00005555555b80da in wasm::HeapType::isSignature (this=0x38) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm-type.h:387
#3  0x000055555616e94e in wasm::HeapType::getSignature (this=0x38) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm/wasm-type.cpp:1148
#4  0x00005555555ba11e in wasm::Function::getSig (this=0x0) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm.h:2091
#5  0x00005555555ba199 in wasm::Function::getResults (this=0x0) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm.h:2093
#6  0x00005555561ba2cf in wasm::FunctionValidator::validateCallParamsAndResult<wasm::Call> (this=0x7fffffffb990, curr=0x555556f8ba60, sigType=..., printable=0x555556f8ba60)
    at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm/wasm-validator.cpp:609
#7  0x00005555561b1882 in wasm::FunctionValidator::validateCallParamsAndResult<wasm::Call> (this=0x7fffffffb990, curr=0x555556f8ba60, sigType=...) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm/wasm-validator.cpp:626
#8  0x00005555561952da in wasm::FunctionValidator::visitCall (this=0x7fffffffb990, curr=0x555556f8ba60) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm/wasm-validator.cpp:941
#9  0x00005555561b7bfa in wasm::Walker<wasm::FunctionValidator, wasm::Visitor<wasm::FunctionValidator, void> >::doVisitCall (self=0x7fffffffb990, currp=0x7fffffffb910) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm-delegations.def:23
#10 0x00005555561adcc4 in wasm::Walker<wasm::FunctionValidator, wasm::Visitor<wasm::FunctionValidator, void> >::walk (this=0x7fffffffb9e8, root=@0x7fffffffb910: 0x555556f8ba60)
    at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm-traversal.h:307
#11 0x00005555561ac979 in wasm::FunctionValidator::validate (this=0x7fffffffb990, curr=0x555556f8ba60) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm/wasm-validator.cpp:261
#12 0x00005555561a0483 in operator() (__closure=0x7fffffffbc30, curr=0x555556f5d2e0) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm/wasm-validator.cpp:3781
#13 0x00005555561a3c5d in wasm::ModuleUtils::iterDefinedGlobals<wasm::validateGlobals(wasm::Module&, wasm::ValidationInfo&)::<lambda(wasm::Global*)> >(wasm::Module &, struct {...}) (wasm=..., visitor=...)
    at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/ir/module-utils.h:158
#14 0x00005555561a0741 in wasm::validateGlobals (module=..., info=...) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm/wasm-validator.cpp:3763
#15 0x00005555561a2f0f in wasm::WasmValidator::validate (this=0x7fffffffc2f0, module=..., flags=2) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm/wasm-validator.cpp:4159
#16 0x00005555561a32bd in wasm::WasmValidator::validate (this=0x7fffffffc2f0, module=..., options=...) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/wasm/wasm-validator.cpp:4192
#17 0x000055555565bdf3 in main (argc=2, argv=0x7fffffffe028) at /home/sofi/fuzzing/binaryen/executables/Debug/binaryen/src/tools/wasm-opt.cpp:298

Valgrind:


valgrind ./wasm-opt ./wast-oob-read.wast 
==908112== Memcheck, a memory error detector
==908112== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==908112== Using Valgrind-3.24.0.GIT and LibVEX; rerun with -h for copyright info
==908112== Command: ./wasm-opt ./wast-oob-read.wast
==908112== 
==908112== Invalid read of size 8
==908112==    at 0x16C0B2: wasm::HeapType::isBasic() const (wasm-type.h:378)
==908112==    by 0xD22813: wasm::HeapType::getKind() const (wasm-type.cpp:1100)
==908112==    by 0x16C0D9: wasm::HeapType::isSignature() const (wasm-type.h:387)
==908112==    by 0xD2294D: wasm::HeapType::getSignature() const (wasm-type.cpp:1148)
==908112==    by 0x16E11D: wasm::Function::getSig() (wasm.h:2091)
==908112==    by 0x16E198: wasm::Function::getResults() (wasm.h:2093)
==908112==    by 0xD6E2CE: void wasm::FunctionValidator::validateCallParamsAndResult<wasm::Call>(wasm::Call*, wasm::HeapType, wasm::Expression*) (wasm-validator.cpp:609)
==908112==    by 0xD65881: void wasm::FunctionValidator::validateCallParamsAndResult<wasm::Call>(wasm::Call*, wasm::HeapType) (wasm-validator.cpp:626)
==908112==    by 0xD492D9: wasm::FunctionValidator::visitCall(wasm::Call*) (wasm-validator.cpp:941)
==908112==    by 0xD6BBF9: wasm::Walker<wasm::FunctionValidator, wasm::Visitor<wasm::FunctionValidator, void> >::doVisitCall(wasm::FunctionValidator*, wasm::Expression**) (wasm-delegations.def:23)
==908112==    by 0xD61CC3: wasm::Walker<wasm::FunctionValidator, wasm::Visitor<wasm::FunctionValidator, void> >::walk(wasm::Expression*&) (wasm-traversal.h:307)
==908112==    by 0xD60978: wasm::FunctionValidator::validate(wasm::Expression*) (wasm-validator.cpp:261)
==908112==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
==908112== 
==908112== 
==908112== Process terminating with default action of signal 11 (SIGSEGV)
==908112==  Access not within mapped region at address 0x38
==908112==    at 0x16C0B2: wasm::HeapType::isBasic() const (wasm-type.h:378)
==908112==    by 0xD22813: wasm::HeapType::getKind() const (wasm-type.cpp:1100)
==908112==    by 0x16C0D9: wasm::HeapType::isSignature() const (wasm-type.h:387)
==908112==    by 0xD2294D: wasm::HeapType::getSignature() const (wasm-type.cpp:1148)
==908112==    by 0x16E11D: wasm::Function::getSig() (wasm.h:2091)
==908112==    by 0x16E198: wasm::Function::getResults() (wasm.h:2093)
==908112==    by 0xD6E2CE: void wasm::FunctionValidator::validateCallParamsAndResult<wasm::Call>(wasm::Call*, wasm::HeapType, wasm::Expression*) (wasm-validator.cpp:609)
==908112==    by 0xD65881: void wasm::FunctionValidator::validateCallParamsAndResult<wasm::Call>(wasm::Call*, wasm::HeapType) (wasm-validator.cpp:626)
==908112==    by 0xD492D9: wasm::FunctionValidator::visitCall(wasm::Call*) (wasm-validator.cpp:941)
==908112==    by 0xD6BBF9: wasm::Walker<wasm::FunctionValidator, wasm::Visitor<wasm::FunctionValidator, void> >::doVisitCall(wasm::FunctionValidator*, wasm::Expression**) (wasm-delegations.def:23)
==908112==    by 0xD61CC3: wasm::Walker<wasm::FunctionValidator, wasm::Visitor<wasm::FunctionValidator, void> >::walk(wasm::Expression*&) (wasm-traversal.h:307)
==908112==    by 0xD60978: wasm::FunctionValidator::validate(wasm::Expression*) (wasm-validator.cpp:261)
==908112==  If you believe this happened as a result of a stack
==908112==  overflow in your program's main thread (unlikely but
==908112==  possible), you can try to increase the size of the
==908112==  main thread stack using the --main-stacksize= flag.
==908112==  The main thread stack size used in this run was 8388608.
==908112== 
==908112== HEAP SUMMARY:
==908112==     in use at exit: 262,200 bytes in 2,055 blocks
==908112==   total heap usage: 3,648 allocs, 1,593 frees, 411,706 bytes allocated
==908112== 
==908112== LEAK SUMMARY:
==908112==    definitely lost: 0 bytes in 0 blocks
==908112==    indirectly lost: 0 bytes in 0 blocks
==908112==      possibly lost: 7,296 bytes in 24 blocks
==908112==    still reachable: 254,904 bytes in 2,031 blocks
==908112==         suppressed: 0 bytes in 0 blocks
==908112== Rerun with --leak-check=full to see details of leaked memory
==908112== 
==908112== For lists of detected and suppressed errors, rerun with: -s
==908112== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault

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