Buffer overrun when parsing comments inside DOCTYPE #39

Closed
aruslan opened this Issue Mar 13, 2015 · 1 comment

Projects

None yet

2 participants

@aruslan
aruslan commented Mar 13, 2015

The following input causes xml_document::load()/load_buffer() to crash under asan:

00000000 3b 3c 21 44 4f 43 54 59 50 45 ef bb bf 3c 3f 78 |;<!DOCTYPE...<?x| 
00000010 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 31 2e 30 22 |ml version="1.0"| 
00000020 3f 3e 3c 21 2d 2d 20 e9 80 b1 e5 a0 b1 e3 82 b4 |?><!-- .........| 
00000030 e3 83 b3 20 ef 83 97 e3 a9 2a 20 2d 2d 3e       |... .....* -->|

It was found using the LLVM coverage-guided in-process fuzzer:
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/README.txt?view=markup

The crash report:

===================================================================10033==
ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60600000efff at pc 0x0000005059fb bp 0x7fff81f81460 sp 0x7fff81f81458
READ of size 1 at 0x60600000efff thread T0
    #0 0x5059fa in pugi::impl::xml_parser::parse_doctype_group(char*, char) (/aruslan/fuzbuz24/parsepugi+0x5059fa)
    #1 0x4eda75 in pugi::impl::xml_parser::parse_exclamation(char*, pugi::xml_node_struct*, unsigned int, char) (/aruslan/fuzbuz24/parsepugi+0x4eda75)
    #2 0x4e6026 in pugi::impl::xml_parser::parse_tree(char*, pugi::xml_node_struct*, unsigned int, char) (/aruslan/fuzbuz24/parsepugi+0x4e6026)
    #3 0x4dc76e in pugi::impl::xml_parser::parse(char*, unsigned long, pugi::impl::xml_document_struct*, pugi::xml_node_struct*, unsigned int) (/aruslan/fuzbuz24/parsepugi+0x4dc76e)
    #4 0x4db913 in pugi::impl::load_buffer_impl(pugi::impl::xml_document_struct*, pugi::xml_node_struct*, void*, unsigned long, unsigned int, pugi::xml_encoding, bool, bool, char**) (/aruslan/fuzbuz24/parsepugi+0x4db913)
    #5 0x4d953f in pugi::xml_document::load_buffer_inplace_own(void*, unsigned long, unsigned int, pugi::xml_encoding) (/aruslan/fuzbuz24/parsepugi+0x4d953f)
    #6 0x4d5da6 in pugi::xml_parse_result pugi::impl::load_stream_impl<char>(pugi::xml_document&, std::basic_istream<char, std::char_traits<char> >&, unsigned int, pugi::xml_encoding) (/aruslan/fuzbuz24/parsepugi+0x4d5da6)
    #7 0x4d412b in pugi::xml_document::load(std::istream&, unsigned int, pugi::xml_encoding) (/aruslan/fuzbuz24/parsepugi+0x4d412b)
    #8 0x4d2fdd in main (/aruslan/fuzbuz24/parsepugi+0x4d2fdd)
    #9 0x7fb70a034ec4 in __libc_start_main /build/buildd/eglibc-2.19/csu/libc-start.c:287
    #10 0x417e33 in _start (/aruslan/fuzbuz24/parsepugi+0x417e33)

0x60600000efff is located 0 bytes to the right of 63-byte region [0x60600000efc0,0x60600000efff)
allocated by thread T0 here:
    #0 0x4af278 in malloc /aruslan/fuzbuz24/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:40
    #1 0x4d9cc3 in pugi::impl::default_allocate(unsigned long) (/aruslan/fuzbuz24/parsepugi+0x4d9cc3)
    #2 0x4d871d in pugi::xml_parse_status pugi::impl::load_stream_data_seek<char>(std::basic_istream<char, std::char_traits<char> >&, void**, unsigned long*) (/aruslan/fuzbuz24/parsepugi+0x4d871d)
    #3 0x4d5bcd in pugi::xml_parse_result pugi::impl::load_stream_impl<char>(pugi::xml_document&, std::basic_istream<char, std::char_traits<char> >&, unsigned int, pugi::xml_encoding) (/aruslan/fuzbuz24/parsepugi+0x4d5bcd)
    #4 0x4d412b in pugi::xml_document::load(std::istream&, unsigned int, pugi::xml_encoding) (/aruslan/fuzbuz24/parsepugi+0x4d412b)
    #5 0x4d2fdd in main (/aruslan/fuzbuz24/parsepugi+0x4d2fdd)
    #6 0x7fb70a034ec4 in __libc_start_main /build/buildd/eglibc-2.19/csu/libc-start.c:287

SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 pugi::impl::xml_parser::parse_doctype_group(char*, char)
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 fa fa fa fa
=>0x0c0c7fff9df0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00[07]
  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
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==10033==ABORTING
@aruslan
aruslan commented Mar 13, 2015

@zeux fixed it in 0542b18

@aruslan aruslan closed this Mar 13, 2015
@zeux zeux added the bug label Mar 13, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment