Hi,
I am running some experiments for AFLAPI and it has found two buffer-overflows (read) in cparse::packToken::str[abi:cxx11] and cparse::calculator::toRPN.
Environment: Ubuntu 18.04 + clang 6.0.0
Poc 1:
// heap_overflow_1.cc
#include "shunting-yard.h"
using namespace cparse;
int main(){
TokenMap vars;
calculator::calculate("C'\\", &vars);
}
Poc 2
// heap_overflow_2.cc
#include "shunting-yard.h"
using namespace cparse;
int main(){
TokenMap vars;
vars["pi"] = 1535;
calculator::calculate("7pi~pp\u0005\u0005\u0005\u0005\u0005\u0005\u0005\u0005\u0005\u0005\u0005\u0005\u0005\u0005\u0005\u0005\u0005\u0005\u0005\x84ipp\u0005?", &vars);
}
Files are here:
heap_overflow_files.zip
To reproduce:
- Complie the pocs and the whole project with ASAN;
- Run pocs
For Poc1, ASAN says:
$ ./heap_overflow_1
=================================================================
==28967==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000005e7b64 at pc 0x000000540fac bp 0x7ffecd066850 sp 0x7ffecd066848
READ of size 1 at 0x0000005e7b64 thread T0
#0 0x540fab in cparse::calculator::toRPN(char const*, cparse::TokenMap, char const*, char const**, cparse::Config_t) /home/ubuntu/some_c_test/cparse/shunting-yard.cpp:359:14
#1 0x54cd52 in cparse::calculator::calculate(char const*, cparse::TokenMap, char const*, char const**) /home/ubuntu/some_c_test/cparse/shunting-yard.cpp:512:27
#2 0x518a1a in main /home/ubuntu/some_c_test/cparse/fuzz/heap_overflow_1.cc:7:2
#3 0x7f7132a53c86 in __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:310
#4 0x41bf89 in _start (/home/ubuntu/some_c_test/cparse/fuzz/heap_overflow_1+0x41bf89)
0x0000005e7b64 is located 0 bytes to the right of global variable '<string literal>' defined in 'heap_overflow_1.cc:7:24' (0x5e7b60) of size 4
'<string literal>' is ascii string 'C'\'
SUMMARY: AddressSanitizer: global-buffer-overflow /home/ubuntu/some_c_test/cparse/shunting-yard.cpp:359:14 in cparse::calculator::toRPN(char const*, cparse::TokenMap, char const*, char const**, cparse::Config_t)
Shadow bytes around the buggy address:
0x0000800b4f10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000800b4f20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000800b4f30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000800b4f40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000800b4f50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0000800b4f60: 00 00 00 00 00 00 00 00 00 00 00 00[04]f9 f9 f9
0x0000800b4f70: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00
0x0000800b4f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000800b4f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000800b4fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000800b4fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==28967==ABORTING
For poc2, ASAN says:
$ ./heap_overflow_2
=================================================================
==31104==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000208 at pc 0x00000058b95e bp 0x7ffdc41d0710 sp 0x7ffdc41d0708
READ of size 8 at 0x603000000208 thread T0
#0 0x58b95d in cparse::packToken::str[abi:cxx11](unsigned int) const /home/ubuntu/some_c_test/cparse/packToken.cpp:200:25
#1 0x58b95d in cparse::packToken::str[abi:cxx11](cparse::TokenBase const*, unsigned int) /home/ubuntu/some_c_test/cparse/packToken.cpp:218
#2 0x52bc86 in cparse::rpnBuilder::handle_token(cparse::TokenBase*) /home/ubuntu/some_c_test/cparse/shunting-yard.cpp:220:69
#3 0x536221 in cparse::calculator::toRPN(char const*, cparse::TokenMap, char const*, char const**, cparse::Config_t) /home/ubuntu/some_c_test/cparse/shunting-yard.cpp:346:16
#4 0x54cc32 in cparse::calculator::calculate(char const*, cparse::TokenMap, char const*, char const**) /home/ubuntu/some_c_test/cparse/shunting-yard.cpp:512:27
#5 0x518c85 in main /home/ubuntu/some_c_test/cparse/fuzz/heap_overflow_2.cc:7:21
#6 0x7fae23be5c86 in __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:310
#7 0x41bf89 in _start (/home/ubuntu/some_c_test/cparse/fuzz/heap_overflow_2+0x41bf89)
0x603000000208 is located 0 bytes to the right of 24-byte region [0x6030000001f0,0x603000000208)
allocated by thread T0 here:
#0 0x5143f0 in operator new(unsigned long) (/home/ubuntu/some_c_test/cparse/fuzz/heap_overflow_2+0x5143f0)
#1 0x51c7b5 in cparse::Token<long>::clone() const /home/ubuntu/some_c_test/cparse/fuzz/../shunting-yard.h:74:12
#2 0x52bc86 in cparse::rpnBuilder::handle_token(cparse::TokenBase*) /home/ubuntu/some_c_test/cparse/shunting-yard.cpp:220:69
#3 0x536221 in cparse::calculator::toRPN(char const*, cparse::TokenMap, char const*, char const**, cparse::Config_t) /home/ubuntu/some_c_test/cparse/shunting-yard.cpp:346:16
#4 0x54cc32 in cparse::calculator::calculate(char const*, cparse::TokenMap, char const*, char const**) /home/ubuntu/some_c_test/cparse/shunting-yard.cpp:512:27
#5 0x518c85 in main /home/ubuntu/some_c_test/cparse/fuzz/heap_overflow_2.cc:7:21
#6 0x7fae23be5c86 in __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:310
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ubuntu/some_c_test/cparse/packToken.cpp:200:25 in cparse::packToken::str[abi:cxx11](unsigned int) const
Shadow bytes around the buggy address:
0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff8000: fa fa fd fd fd fd fa fa 00 00 00 00 fa fa fd fd
0x0c067fff8010: fd fd fa fa 00 00 00 00 fa fa fd fd fd fa fa fa
0x0c067fff8020: 00 00 00 fa fa fa fd fd fd fd fa fa 00 00 00 00
0x0c067fff8030: fa fa 00 00 00 fa fa fa 00 00 00 fa fa fa 00 00
=>0x0c067fff8040: 00[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==31104==ABORTING
Notes that for normal using, it seems that usage above won't happen. However for library's robustness, I report these bugs here.
Hope that helps. 😄
Hi,
I am running some experiments for AFLAPI and it has found two buffer-overflows (read) in
cparse::packToken::str[abi:cxx11]andcparse::calculator::toRPN.Environment: Ubuntu 18.04 + clang 6.0.0
Poc 1:
Poc 2
Files are here:
heap_overflow_files.zip
To reproduce:
For Poc1, ASAN says:
For poc2, ASAN says:
Notes that for normal using, it seems that usage above won't happen. However for library's robustness, I report these bugs here.
Hope that helps. 😄