chafa <= 4bac1466 is vulnerable to an out of bounds read vulnerability. in hpjansson/chafa
Jun 7th 2022
chafa <= 4bac1466 is vulnerable to an out of bounds read vulnerability.
Build chafa with ASAN(address sanitizer)
$ git rev-parse HEAD 4bac14668535c09f6f47552bbd1566097dab4bf8 $ export CFLAGS="-g -O0 -fsanitize=address"; export CXXFLAGS="-g -O0 -fsanitize=address"; export CC=$(which clang-10); export CXX=$(which clang++-10) $ ./autogen.sh $ ./configure --disable-shared $ make -j 8
PoC available here - google-drive
$ ./tools/chafa/chafa /tmp/cc6d16b6c395925244b398c849a02a47625f67dc ================================================================= ==4615==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62a000005259 at pc 0x0000005abae6 bp 0x7ffc0e5fae90 sp 0x7ffc0e5fae88 READ of size 1 at 0x62a000005259 thread T0 #0 0x5abae5 in lzw_decode /tmp/chafa/libnsgif/lzw.c:362:45 #1 0x5a7901 in gif_internal_decode_frame /tmp/chafa/libnsgif/libnsgif.c:868:47 #2 0x5a541c in gif_decode_frame /tmp/chafa/libnsgif/libnsgif.c:1151:16 #3 0x4d89c7 in maybe_decode_frame /tmp/chafa/tools/chafa/gif-loader.c:68:12 #4 0x4d8569 in gif_loader_get_frame_data /tmp/chafa/tools/chafa/gif-loader.c:204:10 #5 0x4d9b47 in media_loader_get_frame_data /tmp/chafa/tools/chafa/media-loader.c:282:12 #6 0x4cea97 in run_generic /tmp/chafa/tools/chafa/chafa.c:1786:22 #7 0x4ce3a6 in run /tmp/chafa/tools/chafa/chafa.c:1923:12 #8 0x4c74a4 in run_all /tmp/chafa/tools/chafa/chafa.c:1983:18 #9 0x4c5dd1 in main /tmp/chafa/tools/chafa/chafa.c:2035:11 #10 0x7fc448ca9c86 in __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:310 #11 0x41ddb9 in _start (/tmp/chafa/tools/chafa/chafa+0x41ddb9) 0x62a000005259 is located 9 bytes to the right of 20560-byte region [0x62a000000200,0x62a000005250) allocated by thread T0 here: #0 0x4964fd in malloc (/tmp/chafa/tools/chafa/chafa+0x4964fd) #1 0x5a9f05 in lzw_context_create /tmp/chafa/libnsgif/lzw.c:91:22 #2 0x5a0823 in gif_initialise /tmp/chafa/libnsgif/libnsgif.c:946:34 #3 0x4d7e21 in gif_loader_new_from_mapping /tmp/chafa/tools/chafa/gif-loader.c:151:16 #4 0x4d93ba in media_loader_new /tmp/chafa/tools/chafa/media-loader.c:213:30 #5 0x4ce8cf in run_generic /tmp/chafa/tools/chafa/chafa.c:1747:20 #6 0x4ce3a6 in run /tmp/chafa/tools/chafa/chafa.c:1923:12 #7 0x4c74a4 in run_all /tmp/chafa/tools/chafa/chafa.c:1983:18 #8 0x4c5dd1 in main /tmp/chafa/tools/chafa/chafa.c:2035:11 #9 0x7fc448ca9c86 in __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:310 SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/chafa/libnsgif/lzw.c:363:45 in lzw_decode Shadow bytes around the buggy address: 0x0c547fff89f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c547fff8a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c547fff8a10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c547fff8a20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c547fff8a30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c547fff8a40: 00 00 00 00 00 00 00 00 00 00 fa[fa]fa fa fa fa 0x0c547fff8a50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c547fff8a60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c547fff8a70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c547fff8a80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c547fff8a90: 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 Shadow gap: cc ==4615==ABORTING
I know that the stacktrace shows
libnsgif which has upstream - https://github.com/netsurf-plan9/libnsgif but this is the only downstream project that has a good security posture. Also the upsteam doesn't build that well with missing instructions. I'll try to build and update here in a later comment.
table is allocated with a fixed size of
1 << LZW_CODE_MAX = 0x1000 members.
But here in the PoC it could be larger
gef➤ print (code >> current_bit) & ((1 << code_size) - 1) $5 = 0x1002
This would read outof the bounds for this array. I haven't looked into much on why we the values get to this state. This PoC is from a fuzzing session.
The vulnerability by itself doesn't seem to have much impact. It can only read out of the bounds and leak some values from the heap. This can only be powerful once paired with any other primitive which can write.
I only report here as I see this project active and the upstream with no activity. If the project owner feels I can defer the report to that project too.