diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 61b423220898..c9a5838a7394 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1289,6 +1289,10 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source) Z_ADDREF(source->handlers.write_header->stream); } ch->handlers.write_header->stream = source->handlers.write_header->stream; + if (!Z_ISUNDEF(source->handlers.std_err)) { + Z_ADDREF(source->handlers.std_err); + } + ch->handlers.std_err = source->handlers.std_err; ch->handlers.write->fp = source->handlers.write->fp; ch->handlers.write_header->fp = source->handlers.write_header->fp; diff --git a/ext/curl/tests/curl_copy_handle_stderr_uaf.phpt b/ext/curl/tests/curl_copy_handle_stderr_uaf.phpt new file mode 100644 index 000000000000..9a46a27dfa0c --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_stderr_uaf.phpt @@ -0,0 +1,38 @@ +--TEST-- +Cloning a curl handle keeps CURLOPT_STDERR tracked so a closed stream is detected on the clone too +--EXTENSIONS-- +curl +--FILE-- + +--CLEAN-- + +--EXPECTF-- +Warning: curl_exec(): CURLOPT_STDERR resource has gone away, resetting to stderr in %s on line %d +%A +string(5) "Test." + +Warning: curl_exec(): CURLOPT_STDERR resource has gone away, resetting to stderr in %s on line %d +%A +string(5) "Test."