diff --git a/NEWS b/NEWS index 140975629a81..a384e8b71422 100644 --- a/NEWS +++ b/NEWS @@ -52,6 +52,8 @@ PHP NEWS parsing fails after Transfer-Encoding). (bercedev) . Fixed bug GH-24509 (HTTP wrapper leaks Location buffer on empty Location header). (bercedev) + . Fixed bug GH-24707 (Use-after-free in opendir() when a user wrapper + unregisters itself). (lazerg) - Zip: . Reject broken libzip versions 1.3.1, 1.7.0 and 1.12.0 during Windows diff --git a/ext/standard/tests/streams/gh24707.phpt b/ext/standard/tests/streams/gh24707.phpt new file mode 100644 index 000000000000..81fb4244bba0 --- /dev/null +++ b/ext/standard/tests/streams/gh24707.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-24707 (Use-after-free in opendir() when a user wrapper unregisters itself) +--FILE-- + +--EXPECTF-- +Warning: opendir(): Failed to open directory: "Wrapper::dir_opendir" call failed in %s on line %d +bool(false) diff --git a/main/streams/streams.c b/main/streams/streams.c index 3c482f4cd52e..55e15c9e3a03 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -2104,6 +2104,8 @@ PHPAPI php_stream *_php_stream_opendir(const char *path, int options, return NULL; } + /* wrapper name needs to be stored as wrapper can be removed in opener (user stream) */ + char *wrapper_name = estrdup(PHP_STREAM_ERROR_WRAPPER_NAME(wrapper)); stream = wrapper->wops->dir_opener(wrapper, path_to_open, "r", options & ~REPORT_ERRORS, NULL, context STREAMS_REL_CC); @@ -2112,10 +2114,11 @@ PHPAPI php_stream *_php_stream_opendir(const char *path, int options, stream->wrapper = wrapper; stream->flags |= PHP_STREAM_FLAG_NO_BUFFER | PHP_STREAM_FLAG_IS_DIR; } else if (options & REPORT_ERRORS) { - php_stream_display_wrapper_errors(wrapper, context, PHP_STREAM_EC(OpenFailed), + php_stream_display_wrapper_name_errors(wrapper_name, context, PHP_STREAM_EC(OpenFailed), "Failed to open directory"); } - php_stream_tidy_wrapper_error_log(wrapper); + php_stream_tidy_wrapper_name_error_log(wrapper_name); + efree(wrapper_name); return stream; }