libyaml
libyaml copied to clipboard
heap-buffer-overflow in yaml_emitter_emit_flow_mapping_key function of emitter.c:810:27
When using libfuzzer to fuzz the dumper, a heap overflow was found, this can reproduce on the lattest commit. When trying to dereference a pointer: (*(--(stack).top)), , the status of the stack is not checked, resulting in an overflow.
Version
git log
commit f8f760f7387d2cc56a2fc7b1be313a3bf3f7f58c (HEAD -> master, origin/master, origin/HEAD)
Author: Tina Müller (tinita) <[email protected]>
Date: Wed Nov 10 18:03:02 2021 +0100
POC file
https://github.com/HotSpurzzZ/testcases/blob/main/libyaml/libyaml_heap_overflow
Verification steps
Compile and run the following file https://github.com/google/oss-fuzz/blob/master/projects/libyaml/libyaml_dumper_fuzzer.c clang -g -fsanitize=address,fuzzer -O0 -I ./src/ -Iinclude -c libyaml_dumper_fuzzer.c -o dumper_fuzzer.o clang++ -g -fsanitize=address,fuzzer -O0 dumper_fuzzer.o -o dumper_fuzzer src/.libs/libyaml.a
AddressSanitizer output
./dumper_fuzzer ./libyaml_heap_overflow =================================================================
==3430052==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6060000001fc at pc 0x00000057c637 bp 0x7fffffffd030 sp 0x7fffffffd028
READ of size 4 at 0x6060000001fc thread T0
#0 0x57c636 in yaml_emitter_emit_flow_mapping_key /home/libyaml_issue/libyaml/src/emitter.c:810:27
#1 0x57a43b in yaml_emitter_state_machine /home/libyaml_issue/libyaml/src/emitter.c:453:20
#2 0x579790 in yaml_emitter_emit /home/libyaml_issue/libyaml/src/emitter.c:291:14
#3 0x566877 in yaml_emitter_close /home/libyaml_issue/libyaml/src/dumper.c:98:10
#4 0x553671 in LLVMFuzzerTestOneInput /home/libyaml_issue/libyaml/dumper_fuzzer.c:268:3
#5 0x4586a1 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/libyaml_issue/libyaml/dumper_fuzzer+0x4586a1)
#6 0x443e12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/home/libyaml_issue/libyaml/dumper_fuzzer+0x443e12)
#7 0x4498c6 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/libyaml_issue/libyaml/dumper_fuzzer+0x4498c6)
#8 0x472582 in main (/home/libyaml_issue/libyaml/dumper_fuzzer+0x472582)
#9 0x7ffff7a6f082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
#10 0x41e4dd in _start (/home/libyaml_issue/libyaml/dumper_fuzzer+0x41e4dd)
0x6060000001fc is located 4 bytes to the left of 64-byte region [0x606000000200,0x606000000240)
allocated by thread T0 here:
#0 0x51e20d in malloc (/home/libyaml_issue/libyaml/dumper_fuzzer+0x51e20d)
#1 0x553ef9 in yaml_malloc /home/libyaml_issue/libyaml/src/api.c:33:12
#2 0x557132 in yaml_emitter_initialize /home/libyaml_issue/libyaml/src/api.c:368:10
#3 0x553353 in LLVMFuzzerTestOneInput /home/libyaml_issue/libyaml/dumper_fuzzer.c:226:8
#4 0x4586a1 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/libyaml_issue/libyaml/dumper_fuzzer+0x4586a1)
#5 0x443e12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/home/libyaml_issue/libyaml/dumper_fuzzer+0x443e12)
#6 0x4498c6 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/libyaml_issue/libyaml/dumper_fuzzer+0x4498c6)
#7 0x472582 in main (/home/libyaml_issue/libyaml/dumper_fuzzer+0x472582)
#8 0x7ffff7a6f082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/libyaml_issue/libyaml/src/emitter.c:810:27 in yaml_emitter_emit_flow_mapping_key
Shadow bytes around the buggy address:
0x0c0c7fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c0c7fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c0c7fff8000: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
0x0c0c7fff8010: 00 00 00 00 00 00 02 fa fa fa fa fa fd fd fd fd
0x0c0c7fff8020: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
=>0x0c0c7fff8030: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa[fa]
0x0c0c7fff8040: 00 00 00 00 00 00 00 00 fa fa fa fa fd fd fd fd
0x0c0c7fff8050: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
0x0c0c7fff8060: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
0x0c0c7fff8070: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
0x0c0c7fff8080: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
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
==3430052==ABORTING```