WebAssembly/wasi-libc

Dereferencing nullptr in __sec_to_zone function

Closed this issue · 2 comments

	*oppoff = 0;

__secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone);

	__secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone);

The problem is that oppoff ptr can be nullptr.

	if (oppoff) {
		*oppoff = 0;
	}

stack unwind information to show the bug

~/Libraries/fast_io/examples/0007.legacy$ wavm run --enable memtag --mount-root . ./construct_fstream_from_syscall
libc-top-half/musl/src/time/__tz.c 436
libc-top-half/musl/src/time/__tz.c 439
libc-top-half/musl/src/time/__tz.c 441
warning: DWARF unit at offset 0x0000002a has unsupported version 0, supported are 2-5
Runtime exception: wavm.invalidMemoryTagAccess
Call stack:
  host!/softwares/wavm/lib/libWAVM.so.0!wavm_memtag_trap_function+41
  wasm!./construct_fstream_from_syscall!__secs_to_zone+7
  wasm!./construct_fstream_from_syscall!__localtime_r+22
  wasm!./construct_fstream_from_syscall!__original_main+314
  wasm!./construct_fstream_from_syscall!_start+13
  thnk!C to WASM thunk!()->()+0
  host!/softwares/wavm/lib/libWAVM.so.0!WAVM::Platform::catchSignals(void (*)(void*), bool (*)(void*, WAVM::Platform::Signal, WAVM::Platform::CallStack&&), void*)+205
  host!/softwares/wavm/lib/libWAVM.so.0!WAVM::Runtime::invokeFunctionWithMemTag(WAVM::Runtime::Context*, WAVM::Runtime::Function const*, WAVM::IR::FunctionType, WAVM::IR::UntaggedValue const*, WAVM::IR::UntaggedValue*, WAVM::LLVMJIT::memtagStatus)+535
  host!wavm+252855
  host!/softwares/wavm/lib/libWAVM.so.0!WAVM::WASI::catchExit(std::function<int ()>&&)+15
  host!wavm+246546
  host!wavm+236837
  host!/softwares/wavm/lib/libWAVM.so.0!WAVM::Platform::catchSignals(void (*)(void*), bool (*)(void*, WAVM::Platform::Signal, WAVM::Platform::CallStack&&), void*)+205
  host!/softwares/wavm/lib/libWAVM.so.0!WAVM::Runtime::catchRuntimeExceptions(std::function<void ()> const&, std::function<void (WAVM::Runtime::Exception*)> const&)+70
  host!wavm+235740
  host!wavm+235511
  host!/usr/lib/libc.so.6+154759
  host!/usr/lib/libc.so.6+139
  host!wavm+72980

Aborted (core dumped)

Since wasi has basically been used for every wasm apps on the web and wasi-libc is static compiled so all binaries have to recompile.

after patching the binary

:~/Libraries/fast_io/examples/0007.legacy$ clang++ -o construct_fstream_from_syscall construct_fstream_from_syscall.cc -s -flto=thin -std=c++26 -I../../include --target=wasm32-wasip1 --sysroot=/home/cqwrteur/toolchains/llvm/sysroots/wasm-sysroots/wasm-noeh-memtag-sysroot/wasm32-wasip1 -fno-exceptions -fno-rtti -Ofast -fsanitize=memtag
:~/Libraries/fast_io/examples/0007.legacy$ wavm run --enable memtag --mount-root . ./construct_fstream_from_syscall
Unix Timestamp:1718406476.713804722
Universe Timestamp:434602343147641676.713804722
UTC:2024-06-14T23:07:56.713804722Z
Local:2024-06-14T23:07:56.713804722Z Timezone:UTC
LLVM clang 19.0.0git (git@github.com:trcrsired/llvm-project.git e41af7174893dcae864e5046ea284948ae197f3b)
LLVM libc++ 190000
fstream.rdbuf():0xa0014ab4
FILE*:0xf0014d20
fd:5
:~/Libraries/fast_io/examples/0007.legacy$ clang++ -o construct_fstream_from_syscall construct_fstream_from_syscall.cc -s -flto=thin -std=c++26 -I../../include  -Ofast -fsanitize=address,undefined -fuse-ld=mold
:~/Libraries/fast_io/examples/0007.legacy$ ./construct_fstream_from_syscall 
Unix Timestamp:1718406535.528581469
Universe Timestamp:434602343147641735.528581469
UTC:2024-06-14T23:08:55.528581469Z
Local:2024-06-14T18:08:55.528581469-05:00 Timezone:EST
LLVM clang 19.0.0git (git@github.com:trcrsired/llvm-project.git e41af7174893dcae864e5046ea284948ae197f3b)
GNU C Library 2.39
GNU C++ Library 14 20240522
fstream.rdbuf():0x00007ffc23d7c988
FILE*:0x0000515000000080
fd:3
:~/Libraries/fast_io/examples/0007.legacy$ clang++ -o construct_fstream_from_syscall construct_fstream_from_syscall.cc -s -flto=thin -std=c++26 -I../../include  -Ofast -fsanitize=address,undefined -fuse-ld=mold -stdlib=libc++
:~/Libraries/fast_io/examples/0007.legacy$ ./construct_fstream_from_syscall 
Unix Timestamp:1718406589.09137612
Universe Timestamp:434602343147641789.09137612
UTC:2024-06-14T23:09:49.09137612Z
Local:2024-06-14T18:09:49.09137612-05:00 Timezone:EST
LLVM clang 19.0.0git (git@github.com:trcrsired/llvm-project.git e41af7174893dcae864e5046ea284948ae197f3b)
GNU C Library 2.39
LLVM libc++ 190000
fstream.rdbuf():0x00007ffcf702b668
FILE*:0x0000515000000080
fd:3

This demonstrates that the issue lies within wasi-libc, not my fast_io library. I recommend transitioning wasi libc to LLVM libc. The ease with which this bug occurs suggests there may be numerous security vulnerabilities in wasi libc from a statistical perspective. Modifying musl is unlikely to address it effectively. I propose involving LLVM developers in maintaining the libc.

Thanks you for the bug report. The code you found it producing a null pointer dereference

// Minimalist implementation for now.
*isdst = 0;
*offset = 0;
*oppoff = 0;
*zonename = __utc;
is a stub in place of the upstream musl implementation, which cannot be supported until timezone is available in new import functions are introduced in WASI 0.2.1. I submitted a fix for the stub #507.