Function ezxml_decode() while parsing crafted XML file performs incorrect memory handling leading to heap buffer overread while running following operations:
for (; *s; s++) { // normalize line endings
while (*s == '\r') {
*(s++) = '\n';
if (*s == '\n') memmove(s, (s + 1), strlen(s));
}
}
=================================================================
==19463==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60600000ef99 at pc 0x000000406d64 bp 0x7ffc47da2340 sp 0x7ffc47da2330
READ of size 1 at 0x60600000ef99 thread T0
0 0x406d63 in ezxml_decode ezxml_0.8.6/ezxml.c:163
1 0x407047 in ezxml_char_content ezxml_0.8.6/ezxml.c:242
2 0x4162f0 in ezxml_parse_str ezxml_0.8.6/ezxml.c:591
3 0x4186f2 in ezxml_parse_fd ezxml_0.8.6/ezxml.c:641
4 0x418a28 in ezxml_parse_file ezxml_0.8.6/ezxml.c:659
5 0x401972 in main ezxml_0.8.6/test_ezxml.c:113
6 0x7fc2b265582f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
7 0x401c78 in _start (ezxml/test_ezxml_asan.exe+0x401c78)
0x60600000ef99 is located 0 bytes to the right of 57-byte region [0x60600000ef60,0x60600000ef99)
allocated by thread T0 here:
0 0x7fc2b2a97961 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98961)
1 0x40ce17 in ezxml_str2utf8 ezxml_0.8.6/ezxml.c:450
SUMMARY: AddressSanitizer: heap-buffer-overflow ezxml_0.8.6/ezxml.c:163 ezxml_decode
Shadow bytes around the buggy address:
0x0c0c7fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0c7fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0c7fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0c7fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0c7fff9de0: fa fa fa fa fa fa fa fa fa fa fa fa 00 00 00 00
=>0x0c0c7fff9df0: 00 00 00[01]fa fa fa fa fd fd fd fd fd fd fd fd
0x0c0c7fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0c7fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0c7fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0c7fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0c7fff9e40: 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
==19463==ABORTING
Reproduction:
Sample XML file leading to crash:
crash_011_heap_overflow_ezxml_decode_163.raw
Code snippet for reproduction:
ezxml_t result = ezxml_parse_file("crash_011_heap_overflow_ezxml_decode_163.raw");
This segfault arises by not properly verifying if there is still data left to read after normalizing line endings. The proposed patch addresses this.