GNOME Bugzilla – Bug 751603
xmlParseXMLDecl: out of bounds heap access if versionencoding="es and any UTF-8 got
Last modified: 2017-06-13 04:23:32 UTC
The attached document will cause an out of bounds heap read access in the function xmlParseXMLDecl. Can be testet with xmllint and address sanitizer This was found with american fuzzy lop. Both 2.9.2 and latest git code are affected. Here's the stack trace from address sanitizer: ==32024==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62100001c900 at pc 0x000000599fb9 bp 0x7ffc797d1b80 sp 0x7ffc797d1b78 READ of size 1 at 0x62100001c900 thread T0 #0 0x599fb8 in xmlParseXMLDecl /f/libxml2-2.9.2/parser.c:10666:2 #1 0x59b0e1 in xmlParseDocument /f/libxml2-2.9.2/parser.c:10771:2 #2 0x5be804 in xmlDoRead /f/libxml2-2.9.2/parser.c:15298:5 #3 0x5beab6 in xmlReadFile /f/libxml2-2.9.2/parser.c:15360:13 #4 0x50114d in parseAndPrintFile /f/libxml2-2.9.2/xmllint.c:2401:9 #5 0x4f8c0f in main /f/libxml2-2.9.2/xmllint.c:3759:7 #6 0x7f7c9e5e9f9f in __libc_start_main /var/tmp/portage/sys-libs/glibc-2.20-r2/work/glibc-2.20/csu/libc-start.c:289 #7 0x44cd26 in _start (/mnt/ram/xml/xmllint+0x44cd26) 0x62100001c900 is located 0 bytes to the right of 4096-byte region [0x62100001b900,0x62100001c900) allocated by thread T0 here: #0 0x4d3cf2 in malloc (/mnt/ram/xml/xmllint+0x4d3cf2) #1 0x7c53f0 in xmlBufCreate /f/libxml2-2.9.2/buf.c:136:32 SUMMARY: AddressSanitizer: heap-buffer-overflow /f/libxml2-2.9.2/parser.c:10666 xmlParseXMLDecl Shadow bytes around the buggy address: 0x0c427fffb8d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c427fffb8e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c427fffb8f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c427fffb900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c427fffb910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c427fffb920:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c427fffb930: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c427fffb940: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c427fffb950: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c427fffb960: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c427fffb970: 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 Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 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 ==32024==ABORTING ==32024==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62100001c900 at pc 0x000000599fb9 bp 0x7ffc797d1b80 sp 0x7ffc797d1b78 READ of size 1 at 0x62100001c900 thread T0 #0 0x599fb8 in xmlParseXMLDecl /f/libxml2-2.9.2/parser.c:10666:2 #1 0x59b0e1 in xmlParseDocument /f/libxml2-2.9.2/parser.c:10771:2 #2 0x5be804 in xmlDoRead /f/libxml2-2.9.2/parser.c:15298:5 #3 0x5beab6 in xmlReadFile /f/libxml2-2.9.2/parser.c:15360:13 #4 0x50114d in parseAndPrintFile /f/libxml2-2.9.2/xmllint.c:2401:9 #5 0x4f8c0f in main /f/libxml2-2.9.2/xmllint.c:3759:7 #6 0x7f7c9e5e9f9f in __libc_start_main /var/tmp/portage/sys-libs/glibc-2.20-r2/work/glibc-2.20/csu/libc-start.c:289 #7 0x44cd26 in _start (/mnt/ram/xml/xmllint+0x44cd26) 0x62100001c900 is located 0 bytes to the right of 4096-byte region [0x62100001b900,0x62100001c900) allocated by thread T0 here: #0 0x4d3cf2 in malloc (/mnt/ram/xml/xmllint+0x4d3cf2) #1 0x7c53f0 in xmlBufCreate /f/libxml2-2.9.2/buf.c:136:32 SUMMARY: AddressSanitizer: heap-buffer-overflow /f/libxml2-2.9.2/parser.c:10666 xmlParseXMLDecl Shadow bytes around the buggy address: 0x0c427fffb8d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c427fffb8e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c427fffb8f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c427fffb900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c427fffb910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c427fffb920:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c427fffb930: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c427fffb940: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c427fffb950: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c427fffb960: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c427fffb970: 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 Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 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 ==32024==ABORTING
I don't see attached document, can you attach?
Created attachment 306248 [details] sample input exposing heap oob
sorry, forgot that...
I'm not sure that you attached correct xml file (xmllint doesn't crash). 1.xml:1: parser error : expected '=' <?xml versionencoding="es� ^ 1.xml:1: parser error : Malformed declaration expecting version <?xml versionencoding="es� ^ 1.xml:1: parser error : Blank needed here <?xml versionencoding="es� ^ 1.xml:1: parser error : String not closed expecting " or ' <?xml versionencoding="es� ^ encoding error : input conversion failed due to input error, bytes 0xE6 0x00 0x78 0x6D 1.xml:1: parser error : switching encoding: encoder error � ^ 1.xml:1: parser error : Blank needed here � ^ encoding error : input conversion failed due to input error, bytes 0xE6 0x00 0x78 0x6D I/O error : encoder error 1.xml:1: parser error : parsing XML declaration: '?>' expected ^ 1.xml:1: parser error : internal error: Huge input lookup ^
Read oob issues usually don't crash. You need to recompile libxml2 with address sanitizer (./configure --disable-shared CFLAGS="-fsanitize=address" LDFLAGS="-fsanitize=address"; make should do it).
ah, yes. I can confirm.
Created attachment 306253 [details] [review] parser: goto whitespace before getting encoding The main problem is that parser parses XML declaration a bit wrong. If we will get `<?xml versionencoding="es">` to parser it will really think that version is NULL and encoding is "es", but it's obviosly wrong, we should add jump to near whitespace after checking version. Reported-By: Hanno Boeck <hanno@hboeck.de> Reference: https://bugzilla.gnome.org/show_bug.cgi?id=751603 Signed-off-by: Igor Gnatenko <ignatenko@src.gnome.org>
Went to look at the problem, indeed a bug, but I disagree with the patch, the problem is that once the unterminated encoding value is found, we should drop the parsed value instead of processing with it. We know at that point that the document is not well formed, so no data will be passed to the user from there. We should not try to convert to a different encoding the remaining of the buffer. The out of bound access does not happen because version is broken it happens because the encoding value is truncated but still processed. Proof is that modifying the document to just add the missing " at the end of encoding, then there is no out of bound access: thinkpad:~/XML -> cat libxml2-oob-heap-xmlParseXMLDecl_1.xml <?xml versionencoding="es"? thinkpad:~/XML -> valgrind ./xmllint libxml2-oob-heap-xmlParseXMLDecl_1.xml libxml2-oob-heap-xmlParseXMLDecl_1.xml:1: parser error : expected '=' <?xml versionencoding="es"? ^ libxml2-oob-heap-xmlParseXMLDecl_1.xml:1: parser error : Malformed declaration expecting version <?xml versionencoding="es"? ^ libxml2-oob-heap-xmlParseXMLDecl_1.xml:1: parser error : Blank needed here <?xml versionencoding="es"? ^ libxml2-oob-heap-xmlParseXMLDecl_1.xml:1: parser error : Blank needed here ? ^ libxml2-oob-heap-xmlParseXMLDecl_1.xml:1: parser error : parsing XML declaration: '?>' expected ? ^ libxml2-oob-heap-xmlParseXMLDecl_1.xml:1: parser error : Start tag expected, '<' not found ^ thinkpad:~/XML -> So I commited a different fix to not try to use encodings if the declaration is truncated. https://git.gnome.org/browse/libxml2/commit/?id=9aa37588ee78a06ca1379a9d9356eab16686099c thanks for the report and the fix attempt ! :-) Daniel
Changed the CVE alias from CVE-2016-4619 to CVE-2015-8317. This is due https://marc.info/?l=oss-security&m=149672646023676&w=2 and cf. https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-4619