tinyxml2 icon indicating copy to clipboard operation
tinyxml2 copied to clipboard

Possible Bug: Global Buffer Overflow in `tinyxml2::XMLPrinter::PushText(char const*, bool)`

Open wangziqi520 opened this issue 6 months ago โ€ข 0 comments

๐Ÿž Bug Report: Global Buffer Overflow in tinyxml2::XMLPrinter::PushText(char const*, bool)

๐Ÿ”ค Summary

A global buffer overflow vulnerability was identified in the function tinyxml2::XMLPrinter::PushText(const char*, bool) located at line 2860 of tinyxml2.cpp. The crash occurred during a read operation involving global memory, indicating an out-of-bounds access that may be exploitable.

๐Ÿ“ Location

  • File: tinyxml2.cpp
  • Function: tinyxml2::XMLPrinter::PushText(const char*, bool)
  • Line: 2860

๐Ÿงช Reproduction Steps

This issue was triggered using the following fuzzing test driver:

extern "C" int LLVMFuzzerTestOneInput_0(const uint8_t *fuzz_data, size_t fuzz_size) {
    XMLDocument doc;
    XMLElement* root;

    doc.Parse("<root>"
              "<child1/>"
              "<child2 name=\"test\"/>"
              "<child3/>"
              "<child4/>"
              "</root>");
    root = doc.RootElement();
    
    FuzzedDataProvider provider(fuzz_data, fuzz_size);
    std::string tmp_string_content_0 = provider.ConsumeRandomLengthString();
    const char* string_content_0 = tmp_string_content_0.c_str();

    XMLHandle handle(root->FirstChildElement());
    XMLHandle result = handle.NextSiblingElement(string_content_0);
    
    result.ToElement()->Name();

    return 0;
}

Although this test case primarily involves XML parsing and traversal logic, it indirectly leads to a call to PushText(), where the invalid memory access occurs.

Root Cause Analysis

The crash occurred inside the following function:

void XMLPrinter::PushText( const char* text, bool cdata )
{
    _textDepth = _depth-1;

    SealElementIfJustOpened();
    if ( cdata ) {
        Write( "<![CDATA[" );
        Write( text );
        Write( "]]>" );
    }
    else {
        PrintString( text, true );
    }
}

AddressSanitizer reported a segmentation fault caused by reading from address 0x000000000088 โ€” which points to the zero page โ€” suggesting that text was nullptr or invalid when passed into Write() or PrintString().

This is likely due to:

  • A missing null-pointer check on text.
  • Improper handling of malformed input strings.
  • Use of text without ensuring it's valid or properly terminated.

The error is classified as a global buffer overflow , meaning the access was outside any allocated buffer, potentially allowing an attacker to read or write adjacent global memory regions.

๐Ÿšจ ASan Error Output

==1752043==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000088
READ of size 4 at 0x7ffce45545b8 thread T0
#0 0x55b447ba0f3a in tinyxml2::XMLPrinter::PushText(char const*, bool)
...
SUMMARY: AddressSanitizer: SEGV /data/cpput_vol/utscript/projects/tinyxml2/tinyxml2_3/tinyxml2.cpp:2860

wangziqi520 avatar Jun 17 '25 06:06 wangziqi520