mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-8.2'
* PHP-8.2: Fix use-after-free when unregistering user stream wrapper from itself
This commit is contained in:
commit
b0037eda26
4 changed files with 42 additions and 4 deletions
3
NEWS
3
NEWS
|
@ -2,6 +2,9 @@ PHP NEWS
|
|||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? ????, PHP 8.3.0beta2
|
||||
|
||||
- Streams:
|
||||
. Fixed bug GH-11735 (Use-after-free when unregistering user stream wrapper
|
||||
from itself). (ilutov)
|
||||
|
||||
20 Jul 2023, PHP 8.3.0beta1
|
||||
|
||||
|
|
16
Zend/tests/gh11735_1.phpt
Normal file
16
Zend/tests/gh11735_1.phpt
Normal file
|
@ -0,0 +1,16 @@
|
|||
--TEST--
|
||||
GH-11735: Use-after-free when unregistering user stream wrapper from user stream wrapper
|
||||
--FILE--
|
||||
<?php
|
||||
class FooWrapper {
|
||||
public $context;
|
||||
public function stream_open($path, $mode, $options, &$opened_path) {
|
||||
stream_wrapper_unregister('foo');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
stream_wrapper_register('foo', 'FooWrapper');
|
||||
var_dump(fopen('foo://bar', 'r'));
|
||||
?>
|
||||
--EXPECTF--
|
||||
resource(%d) of type (stream)
|
17
Zend/tests/gh11735_2.phpt
Normal file
17
Zend/tests/gh11735_2.phpt
Normal file
|
@ -0,0 +1,17 @@
|
|||
--TEST--
|
||||
GH-11735: Use-after-free when unregistering user stream wrapper from user stream wrapper
|
||||
--FILE--
|
||||
<?php
|
||||
class FooWrapper {
|
||||
public $context;
|
||||
public function stream_open($path, $mode, $options, &$opened_path) {
|
||||
stream_wrapper_unregister('foo');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
stream_wrapper_register('foo', 'FooWrapper');
|
||||
var_dump(fopen('foo://bar', 'r'));
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: fopen(foo://bar): Failed to open stream: "FooWrapper::stream_open" call failed in %s on line %d
|
||||
bool(false)
|
|
@ -315,6 +315,8 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *
|
|||
|
||||
us = emalloc(sizeof(*us));
|
||||
us->wrapper = uwrap;
|
||||
/* call_method_if_exists() may unregister the stream wrapper. Hold on to it. */
|
||||
GC_ADDREF(us->wrapper->resource);
|
||||
|
||||
user_stream_create_object(uwrap, context, &us->object);
|
||||
if (Z_TYPE(us->object) == IS_UNDEF) {
|
||||
|
@ -350,8 +352,6 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *
|
|||
|
||||
/* set wrapper data to be a reference to our object */
|
||||
ZVAL_COPY(&stream->wrapperdata, &us->object);
|
||||
|
||||
GC_ADDREF(us->wrapper->resource);
|
||||
} else {
|
||||
php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_OPEN "\" call failed",
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
|
@ -361,6 +361,7 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *
|
|||
if (stream == NULL) {
|
||||
zval_ptr_dtor(&us->object);
|
||||
ZVAL_UNDEF(&us->object);
|
||||
zend_list_delete(us->wrapper->resource);
|
||||
efree(us);
|
||||
}
|
||||
zval_ptr_dtor(&zretval);
|
||||
|
@ -403,6 +404,8 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char
|
|||
|
||||
us = emalloc(sizeof(*us));
|
||||
us->wrapper = uwrap;
|
||||
/* call_method_if_exists() may unregister the stream wrapper. Hold on to it. */
|
||||
GC_ADDREF(us->wrapper->resource);
|
||||
|
||||
user_stream_create_object(uwrap, context, &us->object);
|
||||
if (Z_TYPE(us->object) == IS_UNDEF) {
|
||||
|
@ -425,8 +428,6 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char
|
|||
|
||||
/* set wrapper data to be a reference to our object */
|
||||
ZVAL_COPY(&stream->wrapperdata, &us->object);
|
||||
|
||||
GC_ADDREF(us->wrapper->resource);
|
||||
} else {
|
||||
php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_DIR_OPEN "\" call failed",
|
||||
ZSTR_VAL(us->wrapper->ce->name));
|
||||
|
@ -436,6 +437,7 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char
|
|||
if (stream == NULL) {
|
||||
zval_ptr_dtor(&us->object);
|
||||
ZVAL_UNDEF(&us->object);
|
||||
zend_list_delete(us->wrapper->resource);
|
||||
efree(us);
|
||||
}
|
||||
zval_ptr_dtor(&zretval);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue