Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Segmentation fault during request shutdown when memory limit is exceeded during closure initialization #12073

@mszabo-wikia

Description

@mszabo-wikia

Description

The following code:

<?php

class Wrapper {

	private $cb;

	public function __construct( callable $cb ) {
		$this->cb = $cb;
	}
}

class Dep {
	public function test() {
		echo "test";
	}
}

class ClosureTest {

	public function __construct(
		private Dep $dep,
		private Dep $dep2,
		private Dep $dep3,
		private Dep $dep4,
		private Dep $dep5,
		private Dep $dep6
	) {
	}

	private function output( $i, $k ) {
		echo $i . $k;
	}

	function create( int $i, int $k = 213 ) {
		return new Wrapper( function ( $j ) use ( $k ) {
			$this->output( $j, $k );

			$this->dep->test();
			$this->dep2->test();
			$this->dep3->test();
			$this->dep4->test();
			$this->dep5->test();
			$this->dep6->test();
		} );
	}
}

ini_set( 'memory_limit', '4875K' );

$test = new ClosureTest( new Dep(), new Dep(), new Dep(), new Dep(), new Dep(), new Dep() );
for ( $i = 0; $i < 10_000; $i++ ) {
	$$i = $test->create( $i );
}

reliably segfaults on PHP 8.2, 8.1. and 8.0 with opcache enabled (-dopcache.enable_cli=1).

This is a simplified reproducer—originally seen on PHP 8.0.30, in the FPM SAPI, for a request that hit its configured memory limit on a line of code instantiating a closure: https://github.com/wikimedia/mediawiki/blob/f071c22a9a3e7e399dcf3256c96a952f15291a69/includes/Revision/RevisionStore.php#L1786

There is no segmentation fault if Opcache is disabled.

Backtrace of that original error:

#0  zend_mm_free_heap (ptr=0x7631, heap=0x7ff6cb600040) at /usr/src/php/Zend/zend_alloc.c:1366
#1  _efree (ptr=0x7631) at /usr/src/php/Zend/zend_alloc.c:2551
#2  0x0000559226f12314 in destroy_op_array (op_array=0x7ff6639fc778) at /usr/src/php/Zend/zend_opcode.c:475
#3  0x0000559226f94ec9 in zend_closure_free_storage (object=0x7ff6639fc740) at /usr/src/php/Zend/zend_closures.c:490
#4  0x0000559226fa45aa in zend_objects_store_free_object_storage (objects=objects@entry=0x559227c220c8 <executor_globals+840>, 
    fast_shutdown=fast_shutdown@entry=true) at /usr/src/php/Zend/zend_objects_API.c:104
#5  0x0000559226f0df3f in shutdown_executor () at /usr/src/php/Zend/zend_execute_API.c:339
#6  0x0000559226f1d4a9 in zend_deactivate () at /usr/src/php/Zend/zend.c:1239
#7  0x0000559226eb8559 in php_request_shutdown (dummy=dummy@entry=0x0) at /usr/src/php/main/main.c:1854
#8  0x0000559226c42b8a in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/php/sapi/fpm/fpm/fpm_main.c:1942

PHP Version

PHP 8.2.9

Operating System

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions