SAX1 mode with custom callbacks is broken
Note from maintainers: Unfortunately, someone requested a CVE ID for this bug, but this is not a security issue. Using the XML_PARSE_SAX1 parser option with custom callbacks has always crashed almost immediately and doesn't require a "crafted XML file". This mode of operation was completely broken, so it's safe to assume that noone was using it. Yes, you can crash xmllint if you pass some internal debugging options, but that's it. Also note that you can only reproduce this issue with newer versions of xmllint (v2.11.0) because the --sax --sax1
combination had no effect due to a different bug in xmllint.
Please don't request CVE IDs without getting in touch with maintainers first.
Description
I found a poc which can cause libxml2 crash when fuzz testing.
AddressSanitizer report it as global-buffer-overflow at /libxml2/SAX2.c:1614 in xmlSAX2StartElement().
Steps to reproduce the bug
Normal
$ ../master_libxml2/xmllint --recover --sax1 --sax poc2_min
SAX.setDocumentLocator()
SAX.error: parsing XML declaration: '?>' expected
SAX.startDocument()
fish: “../master_libxml2/xmllint --rec…” terminated by signal SIGSEGV (Address boundary error)
With ASAN
$ ../master_asan_libxml2/xmllint --recover --sax1 --sax poc2_min
SAX.setDocumentLocator()
SAX.error: parsing XML declaration: '?>' expected
SAX.startDocument()
=================================================================
==371262==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55a1675264f0 at pc 0x55a167009956 bp 0x7ffc08cbc5e0 sp 0x7ffc08cbc5d0
READ of size 8 at 0x55a1675264f0 thread T0
#0 0x55a167009955 in xmlSAX2StartElement /home/oceane/fuzz_test/new_run_libxml2/master_asan_libxml2/SAX2.c:1614
#1 0x55a166f639b5 in xmlParseStartTag /home/oceane/fuzz_test/new_run_libxml2/master_asan_libxml2/parser.c:8389
#2 0x55a166f79f37 in xmlParseElementStart /home/oceane/fuzz_test/new_run_libxml2/master_asan_libxml2/parser.c:9780
#3 0x55a166fb1674 in xmlParseElement /home/oceane/fuzz_test/new_run_libxml2/master_asan_libxml2/parser.c:9712
#4 0x55a166fb36e2 in xmlParseDocument /home/oceane/fuzz_test/new_run_libxml2/master_asan_libxml2/parser.c:10569
#5 0x55a166fd561b in xmlDoRead /home/oceane/fuzz_test/new_run_libxml2/master_asan_libxml2/parser.c:14596
#6 0x55a166fd561b in xmlCtxtReadFile /home/oceane/fuzz_test/new_run_libxml2/master_asan_libxml2/parser.c:14829
#7 0x55a166ebb02d in testSAX /home/oceane/fuzz_test/new_run_libxml2/master_asan_libxml2/xmllint.c:1651
#8 0x55a166eaf9b0 in main /home/oceane/fuzz_test/new_run_libxml2/master_asan_libxml2/xmllint.c:3711
#9 0x7f142169a0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)
#10 0x55a166eb650d in _start (/home/oceane/fuzz_test/new_run_libxml2/master_asan_libxml2/xmllint+0x8050d)
0x55a1675264f0 is located 6 bytes to the right of global variable '*.LC113' defined in 'xmllint.c' (0x55a1675264e0) of size 10
'*.LC113' is ascii string 'user_data'
0x55a1675264f0 is located 48 bytes to the left of global variable '*.LC114' defined in 'xmllint.c' (0x55a167526520) of size 43
'*.LC114' is ascii string '%s validation generated an internal error
'
SUMMARY: AddressSanitizer: global-buffer-overflow /home/oceane/fuzz_test/new_run_libxml2/master_asan_libxml2/SAX2.c:1614 in xmlSAX2StartElement
Shadow bytes around the buggy address:
0x0ab4ace9cc40: f9 f9 f9 f9 00 00 00 00 06 f9 f9 f9 f9 f9 f9 f9
0x0ab4ace9cc50: 00 00 06 f9 f9 f9 f9 f9 00 00 00 00 01 f9 f9 f9
0x0ab4ace9cc60: f9 f9 f9 f9 00 00 07 f9 f9 f9 f9 f9 00 f9 f9 f9
0x0ab4ace9cc70: f9 f9 f9 f9 00 00 00 07 f9 f9 f9 f9 00 00 06 f9
0x0ab4ace9cc80: f9 f9 f9 f9 00 06 f9 f9 f9 f9 f9 f9 00 00 06 f9
=>0x0ab4ace9cc90: f9 f9 f9 f9 00 00 03 f9 f9 f9 f9 f9 00 02[f9]f9
0x0ab4ace9cca0: f9 f9 f9 f9 00 00 00 00 00 03 f9 f9 f9 f9 f9 f9
0x0ab4ace9ccb0: 00 00 07 f9 f9 f9 f9 f9 02 f9 f9 f9 f9 f9 f9 f9
0x0ab4ace9ccc0: 04 f9 f9 f9 f9 f9 f9 f9 05 f9 f9 f9 f9 f9 f9 f9
0x0ab4ace9ccd0: 04 f9 f9 f9 f9 f9 f9 f9 03 f9 f9 f9 f9 f9 f9 f9
0x0ab4ace9cce0: 00 00 04 f9 f9 f9 f9 f9 00 00 00 01 f9 f9 f9 f9
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
==371262==ABORTING
POC
Platform(s)
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Ubuntu 20.04.4 LTS
Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz
Version
$ git log --oneline -1
d6882f64 (HEAD -> master, origin/master, origin/HEAD) threads: Fix startup crash with weak symbol hack
$ ../master_asan_libxml2/xmllint --version
../master_asan_libxml2/xmllint: using libxml version 21200-GITv2.11.0-33-gd6882f64
compiled with: Threads Tree Output Push Reader Patterns Writer SAXv1 HTTP DTDValid HTML C14N Catalog XPath XPointer XInclude Iconv ISO8859X Unicode Regexps Automata Schemas Schematron Modules Debug Zlib Lzma