php / php-src

The PHP Interpreter
https://www.php.net
Other
38.12k stars 7.74k forks source link

Segmentation fault with frameless functions and undefined CVs #16009

Closed YuanchengJiang closed 3 weeks ago

YuanchengJiang commented 3 weeks ago

Description

The following code:

<?php
$dom = DOM\XMLDocument::createFromString(<<<XML
<html xmlns="http://www.w3.org/1999/xhtml">
<input type="text" placeholder="" />
<textarea placeholder="" />
<input xmlns="" type="text" placeholder="" />
<textarea xmlns="" placeholder="" />
<input type="text" />
<textarea />
</html>
XML);
$fusion = $dom;
function testMin2First(int $value): int {
        $value = min($value, 100);
        return $value;
}
function testMin2Second(int $fusion): int {
        $value = min(100, $value);
        return $value;
}
function testMin2_TMP(int $value): int {
        $value = min($value + 1, 100);
        return $value;
}
var_dump(testMin2First(5));
var_dump(testMin2Second(5));
?>

Resulted in this output:

/php-src/main/spprintf.c:376:14: runtime error: member access within misaligned address 0x200238000000002 for type 'zend_string' (aka 'struct _zend_string'), which requires 8 byte alignment

To reproduce:

-d "extension_dir=/php-src/modules/" -d "zend_extension=/php-src/modules/opcache.so" -d "opcache.enable=1" -d "opcache.enable_cli=1" -d "opcache.jit=1012"

PHP Version

PHP 8.4.0-dev

Operating System

ubuntu 22.04

DanielEScherzer commented 3 weeks ago
Smaller reproduction, but not minimal given the report below ``` "); $fusion = $dom; function testMin2First(int $value): int { return min($value, 100); } function testMin2Second(int $fusion): int { $value = min(100, $value); return $value; } function testMin2_TMP(int $value): int { return min($value + 1, 100); } testMin2Second(5); ```
nielsdos commented 3 weeks ago

More minimal:

<?php
function testMin2Second(): int {
    $value = min(100, $value);
    return $value;
}
function testMin2_TMP(int $value): int {
    return min($value + 1, 100);
}
testMin2Second();

ASAN:

==3604==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x5666e7a5a809 bp 0x7ffd589392b0 sp 0x7ffd58938cb0 T0)
==3604==The signal is caused by a READ memory access.
==3604==Hint: this fault was caused by a dereference of a high value address (see register values below).  Disassemble the provided pc to learn which register was used.
    #0 0x5666e7a5a809 in xbuf_format_converter /run/media/niels/MoreData/php-src/main/spprintf.c:376
    #1 0x5666e7a5e76e in php_printf_to_smart_str /run/media/niels/MoreData/php-src/main/spprintf.c:784
    #2 0x5666e7fbd224 in zend_vstrpprintf /run/media/niels/MoreData/php-src/Zend/zend.c:338
    #3 0x5666e7fc32b9 in zend_error_va_list /run/media/niels/MoreData/php-src/Zend/zend.c:1589
    #4 0x5666e7fc3cdc in zend_error_unchecked /run/media/niels/MoreData/php-src/Zend/zend.c:1664
    #5 0x78f3c2a79eba in zend_jit_undefined_op_helper ext/opcache/jit/zend_jit_helpers.c:351
    #6 0x49451cfe  (/dev/zero (deleted)+0x8000cfe)

Reminds me of the other issue that had some type+value store missing. In this case for undef variables probably.

EDIT: also if you change the code to the following, you get an interesting error message:

<?php
function testMin2Second(): int {
    $value = min(100, $value);
    return $value;
}
testMin2Second();

Gives: Warning: Undefined variable $testmin2second

nielsdos commented 3 weeks ago

It's related to FLFs, as removing the annotation fixes OP's issue and the strange undefined variable one I reported.

nielsdos commented 3 weeks ago

I think I got it, after we perform zend_jit_zval_check_undef we may need to update the op addresses, I'll test this a bit and make a PR.