php / php-src

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

Segmentation fault in Zend/zend_execute.c:4624 #16321

Open YuanchengJiang opened 1 month ago

YuanchengJiang commented 1 month ago

Description

The following code:

<?php
require 'filter_errors.inc';
class test_filter4 extends php_user_filter {
function filter($in, $out, &$consumed, $closing): int {
if (!$fusion) {
$bucket = stream_bucket_new($this->stream, "42");
}
return PSFS_ERR_FATAL;
}
}
for($i = 0; $i < 5; ++$i) {
var_dump(stream_filter_register("test_filter$i", "test_filter$i"));
filter_errors_test("test_filter$i", "42");
}

Resulted in this output:

/php-src/Zend/zend_execute.c:4624:8: runtime error: member access within misaligned address 0x000000000004 for type 'zend_execute_data' (aka 'struct _zend_execute_data'), which requires 8 byte alignment
0x000000000004: note: pointer points here
<memory cannot be printed>
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /php-src/Zend/zend_execute.c:4624:8

To reproduce:

-d "opcache.jit_hot_func=1" -d "opcache.jit_hot_return=1" -d "zend_extension=/php-src/modules/opcache.so" -d "opcache.enable_cli=1" -d "opcache.jit=0151"

PHP Version

PHP 8.4.0-dev

Operating System

ubuntu 22.04

cmb69 commented 1 month ago

Simplified reproducer:

require __DIR__ . '/ext/standard/tests/filters/filter_errors.inc';
class test_filter4 extends php_user_filter {
    function filter($in, $out, &$consumed, $closing): int {
        stream_bucket_new($this->stream, "42");
        return PSFS_ERR_FATAL;
    }
}
var_dump(stream_filter_register("test_filter4", "test_filter4"));
filter_errors_test("test_filter4", "42");
arnaud-lb commented 1 month ago

What appears to be happening is:

We should avoid freeing the resource if its refcount is non-zero after dtor, but it has already been removed from the rsrc list at this point so it would leak. Also, if we do not free it immediately after dtor we should probably avoid calling dtor a second time later.

Conversion to objects would probably fix this.