Skip to content

zend_string_init with NULL pointer in simplexml (UB) #19988

Closed

Description

@YuanchengJiang

Description

The following code:

<?php
class AdvancedXMLElement extends SimpleXMLElement {
}
$sxe = simplexml_load_file(__DIR__ . '/53965/collection.xml', AdvancedXMLElement::class);
$processor = new XSLTProcessor;
$dom = new DOMDocument;
$dom->load(__DIR__ . '/53965/collection.xsl');
$processor->importStylesheet($dom);
$result = $processor->transformToDoc($sxe, AdvancedXMLElement::class);
$fusion = $result;
var_dump($fusion->getName());

Resulted in this output:

/home/phpfuzz/WorkSpace/flowfusion/php-src/Zend/zend_string.h:191:24: runtime error: null pointer passed as argument 2, which is declared to never be null
/usr/include/string.h:44:28: note: nonnull attribute specified here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /home/phpfuzz/WorkSpace/flowfusion/php-src/Zend/zend_string.h:191:24 in 

To reproduce:

./php-src/sapi/cli/php  ./test.php

Commit:

ee2da6d9e9745ec83b02b1e5c5a07e8dbd5f9f98

Configurations:

CC="clang-12" CXX="clang++-12" CFLAGS="-DZEND_VERIFY_TYPE_INFERENCE" CXXFLAGS="-DZEND_VERIFY_TYPE_INFERENCE" ./configure --enable-debug --enable-address-sanitizer --enable-undefined-sanitizer --enable-re2c-cgoto --enable-fpm --enable-litespeed --enable-phpdbg-debug --enable-zts --enable-bcmath --enable-calendar --enable-dba --enable-dl-test --enable-exif --enable-ftp --enable-gd --enable-gd-jis-conv --enable-mbstring --enable-pcntl --enable-shmop --enable-soap --enable-sockets --enable-sysvmsg --enable-zend-test --with-zlib --with-bz2 --with-curl --with-enchant --with-gettext --with-gmp --with-mhash --with-ldap --with-libedit --with-readline --with-snmp --with-sodium --with-xsl --with-zip --with-mysqli --with-pdo-mysql --with-pdo-pgsql --with-pgsql --with-sqlite3 --with-pdo-sqlite --with-webp --with-jpeg --with-freetype --enable-sigchild --with-readline --with-pcre-jit --with-iconv

Operating System:

Ubuntu 20.04 Host, Docker 0599jiangyc/flowfusion:latest

This report is automatically generated by FlowFusion

PHP Version

nightly

Operating System

No response

Activity

  1. self-assigned this
    on Sep 29, 2025
  2. ndossche commented on Sep 29, 2025

    @ndossche
    Member

    Slightly reduced and easier:

    <?php
    $sxe = simplexml_load_file(__DIR__ . '/ext/xsl/tests/53965/collection.xml');
    $processor = new XSLTProcessor;
    $dom = new DOMDocument;
    $dom->load(__DIR__ . '/ext/xsl/tests/53965/collection.xsl');
    $processor->importStylesheet($dom);
    $result = $processor->transformToDoc($sxe, SimpleXMLElement::class);
    var_dump($result->getName());
  3. ndossche commented on Sep 29, 2025

    @ndossche
    Member

    Not sure why this is NULL in the first place, I'll have to figure it out. If it is legit that this is NULL then the following patch would work:

    diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
    index 78653cf7ef6..aa903668152 100644
    --- a/ext/simplexml/simplexml.c
    +++ b/ext/simplexml/simplexml.c
    @@ -1628,10 +1628,11 @@ PHP_METHOD(SimpleXMLElement, getName)
     	node = php_sxe_get_first_node_non_destructive(sxe, node);
     	if (node) {
     		namelen = xmlStrlen(node->name);
    -		RETURN_STRINGL((char*)node->name, namelen);
    -	} else {
    -		RETURN_EMPTY_STRING();
    +		if (namelen) {
    +			RETURN_STRINGL((char*)node->name, namelen);
    +		}
     	}
    +	RETURN_EMPTY_STRING();
     }
     /* }}} */
     
  4. ndossche commented on Sep 29, 2025

    @ndossche
    Member

    It's also not a SEGV, this does not crash my system but it's UB.

  5. changed the title [-]SEGV zend_string.h unexpected null pointer[/-] [+]zend_string_init with NULL pointer in simplexml (UB)[/+] on Sep 29, 2025
  6. ndossche commented on Sep 29, 2025

    @ndossche
    Member

    It may also be worthwhile to use ZVAL_STRINGL_FAST as many tags tend to be one char.

  7. ndossche commented on Sep 29, 2025

    @ndossche
    Member

    The problem is that the SimpleXMLElement is a document... Normally this isn't possible, i.e. it's always the root of a document that is pointed at, but xsl allows you to bypass this apparently. You can see this when you try importing a document via simplexml_import_dom.
    A document indeed has no name.
    Changing this to use the root element is breaking, and I see now technical reason why the importing of document nodes should be disallowed, so I'll just fix getName() probably.

  8. added 4 commits that reference this issue on Sep 29, 2025
    b8b23bd
    d94846c
    1bda46e
    c1a6627
  9. added a commit that references this issue on Sep 29, 2025
    4db8993
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions