Skip to content

Segmentation fault on unknown address 0x0001ffff8041 with XML extension under certain memory limit #14124

Closed
@YuanchengJiang

Description

@YuanchengJiang

Description

The following code:

<?php
function createParser(bool $huge) {
    $parser = xml_parser_create();
    xml_parser_set_option($parser, XML_OPTION_PARSE_HUGE, $huge);
    xml_set_element_handler($parser, function($parser, $data) {
    }, function($parser, $data) {
    });
    return $parser;
}
// Construct XML that is too large to parse without XML_OPTION_PARSE_HUGE
$long_text = str_repeat("A", 1000 * 1000 * 5 /* 5 MB */);
$long_xml_head = "<?xml version=\"1.0\"?><container><$long_text/><$long_text/><second>foo</second>";
$long_xml_tail = "</container>";
$parser = createParser(false);
$ret = xml_parse($parser, $long_xml_head, true);
echo "ret = $ret (", xml_error_string(xml_get_error_code($parser)), ")\n";
$parser = createParser(true);
$ret = xml_parse($parser, $long_xml_head, false);
$parser = createParser(true);
$ret = xml_parse_into_struct($parser, $long_xml_head . $long_xml_tail, $values, $index);
?>

Resulted in this output:

ret = 0 (XML_ERR_NAME_REQUIRED)

Fatal error: Allowed memory size of 34603008 bytes exhausted at /php-src/Zend/zend_string.h:176 (tried to allocate 5000032 bytes) in ./test.php on line 20
AddressSanitizer:DEADLYSIGNAL
=================================================================
==2886881==ERROR: AddressSanitizer: SEGV on unknown address 0x0001ffff8041 (pc 0x55f2c377c0ab bp 0x7ffeb917e630 sp 0x7ffeb917e570 T0)
==2886881==The signal is caused by a READ memory access.
    #0 0x55f2c377c0ab in zend_mm_free_heap /php-src/Zend/zend_alloc.c:1431:28
    #1 0x55f2c3780951 in _efree /php-src/Zend/zend_alloc.c:2600:2
    #2 0x55f2c34a76d2 in xml_parser_free_ltags /php-src/ext/xml/xml.c:324:4
    #3 0x55f2c347d3d2 in xml_parser_free_obj /php-src/ext/xml/xml.c:336:2
    #4 0x55f2c4381d2b in zend_objects_store_free_object_storage /php-src/Zend/zend_objects_API.c:122:6
    #5 0x55f2c38b8399 in zend_shutdown_executor_values /php-src/Zend/zend_execute_API.c:401:2
    #6 0x55f2c38b97be in shutdown_executor /php-src/Zend/zend_execute_API.c:418:2
    #7 0x55f2c3989343 in zend_deactivate /php-src/Zend/zend.c:1311:2
    #8 0x55f2c34f319f in php_request_shutdown /php-src/main/main.c:1894:2
    #9 0x55f2c48c9868 in do_cli /php-src/sapi/cli/php_cli.c:1136:3
    #10 0x55f2c48c3b02 in main /php-src/sapi/cli/php_cli.c:1340:18
    #11 0x7f860337ed8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #12 0x7f860337ee3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #13 0x55f2c18031f4 in _start (/php-src/sapi/cli/php+0x1c031f4) (BuildId: 4b2c3013b167e0ff55e0ad4f26ad7d3438ee4f65)

AddressSanitizer can not provide additional info.

To reproduce:

USE_ZEND_ALLOC=1 /WorkSpace/phptest/php-src/sapi/cli/php -d "memory_limit=33M" ./test.php

Setting memory_limit to 25M or 50M outputs leaked memory:

==2935312==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 5000001 byte(s) in 1 object(s) allocated from:
    #0 0x55ef07c88c1e in malloc (/php-src/sapi/cli/php+0x1c88c1e) (BuildId: 4b2c3013b167e0ff55e0ad4f26ad7d3438ee4f65)
    #1 0x7f5e94e917f2 in xmlStrdup (/lib/x86_64-linux-gnu/libxml2.so.2+0xe37f2) (BuildId: aebf8e42966c3ce475ff9d9d51a762831adcbb61)

SUMMARY: AddressSanitizer: 5000001 byte(s) leaked in 1 allocation(s)

PHP Version

PHP 8.4.0-dev

Operating System

ubuntu 22.04

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions