Skip to content

Posibble Bug: Stack Buffer Underflow in tinyxml2::XMLPrinter::PrepareForNewNode(bool) #1030

@wangziqi520

Description

@wangziqi520

🐞 Bug Report: Stack Buffer Underflow in tinyxml2::XMLPrinter::PrepareForNewNode(bool)

🔤 Summary

A stack buffer underflow vulnerability was detected in the function tinyxml2::XMLPrinter::PrepareForNewNode(bool) located in tinyxml2.cpp at line 2739. The issue occurs when reading from an invalid memory address on the stack, potentially leading to information leakage or arbitrary code execution.

📍 Location

  • File: tinyxml2.cpp
  • Function: tinyxml2::XMLPrinter::PrepareForNewNode(bool)
  • Line: 2739

🧪 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) {
    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();

    StrPair strPair;
    strPair.SetStr(string_content_0);
    strPair.Reset();
    strPair.Empty();

    return 0;
}

Although this test case does not directly invoke XML printing functionality, it indirectly leads to a call to PrepareForNewNode() through internal XML processing logic.

🧠 Root Cause Analysis

The function PrepareForNewNode() performs a read operation that accesses memory outside the valid stack frame:

void XMLPrinter::PrepareForNewNode( bool compactMode )
{
    SealElementIfJustOpened();

    if ( compactMode ) {
        return;
    }

    if ( _firstElement ) {
        PrintSpace (_depth); // ← Possible out-of-bounds access here
    } else if ( _textDepth < 0 ) {
        Putc( '\n' );
        PrintSpace( _depth );
    }

    _firstElement = false;
}

The problem occurs inside the call to PrintSpace(_depth), where _depth may be used to calculate an invalid offset on the stack buffer. AddressSanitizer reports a stack-buffer-underflow , indicating that the code reads before the start of a local variable's allocated space.

This is likely due to incorrect bounds checking or improper handling of _depth when computing indentation spaces.

🚨 ASan Error Output

==2875063==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7ffce45545b8
READ of size 4 at 0x7ffce45545b8 thread T0
#0 0x55bef7268b8d in tinyxml2::XMLPrinter::PrepareForNewNode(bool)
...
SUMMARY: AddressSanitizer: stack-buffer-underflow /data/cpput_vol/utscript/projects/tinyxml2/tinyxml2_4/tinyxml2.cpp:2739

AddressSanitizer confirms that the read access occurred before the beginning of a local stack object.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions