Assertion in TiXmlBase::StringEqual can cause DoS
Brought to you by:
leethomason
This vulnerability is caused by the following code:
bool TiXmlBase::StringEqual( const char* p, const char* tag, bool ignoreCase, TiXmlEncoding encoding ) { assert( p ); assert( tag ); if ( !p || !*p ) { assert( 0 ); return false; }
My program for testing:
#include "tinyxml.h" #include <stdlib.h> #include <string> int main(int argc, char*argv[]){ char buf[10240]; if(argc < 2){ printf("args error\n"); return 0; } FILE *f = fopen(argv[1], "rb"); size_t len = fread(buf, 1, sizeof(buf), f); std::string s(buf, sizeof(buf)); TiXmlDocument doc; doc.Parse(s.c_str()); fclose(f); return 0; }
Result:
test_input: tinyxmlparser.cpp:543: static bool TiXmlBase::StringEqual(const char *, const char *, bool, TiXmlEncoding): Assertion `0' failed. [1] 1843 abort ./test_input minimized_crash
And I use libfuzzer to get more detailed output:
harness2: tinyxmlparser.cpp:543: static bool TiXmlBase::StringEqual(const char *, const char *, bool, TiXmlEncoding): Assertion `0' failed. ==1849== ERROR: libFuzzer: deadly signal #0 0x527e41 in __sanitizer_print_stack_trace (/home/presler/fuzzing/tinyxml/harness2+0x527e41) #1 0x472f98 in fuzzer::PrintStackTrace() (/home/presler/fuzzing/tinyxml/harness2+0x472f98) #2 0x4580e3 in fuzzer::Fuzzer::CrashCallback() (/home/presler/fuzzing/tinyxml/harness2+0x4580e3) #3 0x7f07d48103bf (/lib/x86_64-linux-gnu/libpthread.so.0+0x153bf) #4 0x7f07d462118a in __libc_signal_restore_set /build/glibc-eX1tMB/glibc-2.31/signal/../sysdeps/unix/sysv/linux/internal-signals.h:86:3 #5 0x7f07d462118a in raise /build/glibc-eX1tMB/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:48:3 #6 0x7f07d4600858 in abort /build/glibc-eX1tMB/glibc-2.31/stdlib/abort.c:79:7 #7 0x7f07d4600728 in __assert_fail_base /build/glibc-eX1tMB/glibc-2.31/assert/assert.c:92:3 #8 0x7f07d4611f35 in __assert_fail /build/glibc-eX1tMB/glibc-2.31/assert/assert.c:101:3 #9 0x558e38 in TiXmlBase::StringEqual(char const*, char const*, bool, TiXmlEncoding) /home/presler/fuzzing/tinyxml/tinyxmlparser.cpp:543:3 #10 0x55b25c in TiXmlDeclaration::Parse(char const*, TiXmlParsingData*, TiXmlEncoding) /home/presler/fuzzing/tinyxml/tinyxmlparser.cpp:1603:8 #11 0x55a4bc in TiXmlElement::ReadValue(char const*, TiXmlParsingData*, TiXmlEncoding) /home/presler/fuzzing/tinyxml/tinyxmlparser.cpp:1229:16 #12 0x559e3a in TiXmlElement::Parse(char const*, TiXmlParsingData*, TiXmlEncoding) /home/presler/fuzzing/tinyxml/tinyxmlparser.cpp:1109:8 #13 0x55949a in TiXmlDocument::Parse(char const*, TiXmlParsingData*, TiXmlEncoding) /home/presler/fuzzing/tinyxml/tinyxmlparser.cpp:759:14 #14 0x551699 in LLVMFuzzerTestOneInput /home/presler/fuzzing/tinyxml/harness2.cpp:17:9 #15 0x4597a1 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/presler/fuzzing/tinyxml/harness2+0x4597a1) #16 0x444f12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/home/presler/fuzzing/tinyxml/harness2+0x444f12) #17 0x44a9c6 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/presler/fuzzing/tinyxml/harness2+0x44a9c6) #18 0x473682 in main (/home/presler/fuzzing/tinyxml/harness2+0x473682) #19 0x7f07d46020b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16 #20 0x41f5dd in _start (/home/presler/fuzzing/tinyxml/harness2+0x41f5dd) NOTE: libFuzzer has rudimentary signal handlers. Combine libFuzzer with AddressSanitizer or similar for better crash reports. SUMMARY: libFuzzer: deadly signal
Test case also was attached