Menu

#142 Assertion in TiXmlBase::StringEqual can cause DoS

open
6
2022-01-17
2022-01-17
Nikita
No

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

1 Attachments

Discussion


Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.