llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.01k stars 11.96k forks source link

Stack-overflow in demangler (11) #32236

Open llvmbot opened 7 years ago

llvmbot commented 7 years ago
Bugzilla Link 32889
Version unspecified
OS Linux
Reporter LLVM Bugzilla Contributor
CC @emaste,@mclow

Extended Description

Dear All,

This bug was found with AFLGo, a directed version of AFL/AFLFast. Thanks also to Marcel Böhme and Van-Thuan Pham.

First, you need to build the project (https://github.com/llvm-mirror/libcxxabi/blob/master/fuzz/cxa_demangle_fuzzer.cpp) to obtain the binary file.

To reproduce: $ printf "DTc" > test $ for o in $(seq 1 15000); do printf "o"; done >> test; echo "" >> test; cat test | ./cxa_demangle_fuzzer Segmentation fault

ASAN says: ==30344==ERROR: AddressSanitizer: stack-overflow on address 0x7fffe25c2700 (pc 0x0000006c554e bp 0x7fffe25c4eb0 sp 0x7fffe25c2700 T0)

​0 0x6c554d in char const __cxxabiv1::(anonymous namespace)::parse_expression<__cxxabiv1::(anonymous namespace)::Db>(char const, char const*, __cxxabiv1::(anonymous namespace)::Db&) /src/llvm_libcxxabi/src/cxa_demangle.cpp:3321

#&#8203;1 0x75db2f in char const* __cxxabiv1::(anonymous namespace)::parse_binary_expression<__cxxabiv1::(anonymous namespace)::Db>(char const*, char const*, __cxxabiv1::(anonymous namespace)::Db::String const&, __cxxabiv1::(anonymous namespace)::Db&) /src/llvm_libcxxabi/src/cxa_demangle.cpp:3252:22
#&#8203;2 0x6c862f in char const* __cxxabiv1::(anonymous namespace)::parse_expression<__cxxabiv1::(anonymous namespace)::Db>(char const*, char const*, __cxxabiv1::(anonymous namespace)::Db&) /src/llvm_libcxxabi/src/cxa_demangle.cpp:3620:21
#&#8203;3 0x75db2f in char const* __cxxabiv1::(anonymous namespace)::parse_binary_expression<__cxxabiv1::(anonymous namespace)::Db>(char const*, char const*, __cxxabiv1::(anonymous namespace)::Db::String const&, __cxxabiv1::(anonymous namespace)::Db&) /src/llvm_libcxxabi/src/cxa_demangle.cpp:3252:22
#&#8203;4 0x6c862f in char const* __cxxabiv1::(anonymous namespace)::parse_expression<__cxxabiv1::(anonymous namespace)::Db>(char const*, char const*, __cxxabiv1::(anonymous namespace)::Db&) /src/llvm_libcxxabi/src/cxa_demangle.cpp:3620:21
#&#8203;5 0x75db2f in char const* __cxxabiv1::(anonymous namespace)::parse_binary_expression<__cxxabiv1::(anonymous namespace)::Db>(char const*, char const*, __cxxabiv1::(anonymous namespace)::Db::String const&, __cxxabiv1::(anonymous namespace)::Db&) /src/llvm_libcxxabi/src/cxa_demangle.cpp:3252:22
#&#8203;6 0x6c862f in char const* __cxxabiv1::(anonymous namespace)::parse_expression<__cxxabiv1::(anonymous namespace)::Db>(char const*, char const*, __cxxabiv1::(anonymous namespace)::Db&) /src/llvm_libcxxabi/src/cxa_demangle.cpp:3620:21

Regards, Manh-Dung Nguyen

urnathan commented 2 years ago

The demangler uses a recursive descent parser, and is processing untrusted user input. This results in a terrible failure mode. If we could use C++20, coroutines would be the natural way to implement a non-stack-recursive parser.