From 6eb3faef3bc1df238b824630dbdcd95c27ddb2f8 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 16 Sep 2025 13:39:35 +0200 Subject: [PATCH 1/2] Fix use-of-uninitialized-value in zend_get_arg_offset_by_name() Don't access fbc->op_array.refcount on internal function. Don't attempt to cache ZEND_ACC_USER_ARG_INFO at all, which is only used in zend_get_closure_invoke_method(). This may reuse arg_info from a temporary closure, and hence caching would also be unsafe. Also avoid populating the cache slot for variadic parameters, where the ZEND_ACC_USER_ARG_INFO is set for the same reason. Closes GH-19856 --- Zend/zend_execute.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 4e6339ca901cb..d44af38c64c63 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -5072,9 +5072,9 @@ static zend_always_inline uint32_t zend_get_arg_offset_by_name( if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) || EXPECTED(fbc->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) { for (uint32_t i = 0; i < num_args; i++) { - zend_arg_info *arg_info = &fbc->op_array.arg_info[i]; + zend_arg_info *arg_info = &fbc->common.arg_info[i]; if (zend_string_equals(arg_name, arg_info->name)) { - if (!fbc->op_array.refcount || !(fbc->op_array.fn_flags & ZEND_ACC_CLOSURE)) { + if (fbc->type == ZEND_USER_FUNCTION && (!fbc->op_array.refcount || !(fbc->op_array.fn_flags & ZEND_ACC_CLOSURE))) { *cache_slot = unique_id; *(uintptr_t *)(cache_slot + 1) = i; } @@ -5094,7 +5094,10 @@ static zend_always_inline uint32_t zend_get_arg_offset_by_name( } if (fbc->common.fn_flags & ZEND_ACC_VARIADIC) { - if (fbc->type == ZEND_INTERNAL_FUNCTION || !fbc->op_array.refcount || !(fbc->op_array.fn_flags & ZEND_ACC_CLOSURE)) { + if ((fbc->type == ZEND_USER_FUNCTION + && (!fbc->op_array.refcount || !(fbc->op_array.fn_flags & ZEND_ACC_CLOSURE))) + || (fbc->type == ZEND_INTERNAL_FUNCTION + && !(fbc->common.fn_flags & ZEND_ACC_USER_ARG_INFO))) { *cache_slot = unique_id; *(uintptr_t *)(cache_slot + 1) = fbc->common.num_args; } From 4b6c465588bf0aee11d7b176f61f4634c2e13467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Wed, 17 Sep 2025 17:03:06 +0200 Subject: [PATCH 2/2] Implement curl_copy_handle in terms of object cloning (#19841) This prevents the implementations from going out of sync, causing bugs like php/php-src#19813. --- ext/curl/interface.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/ext/curl/interface.c b/ext/curl/interface.c index e9e9cd5e409af..4bd6cd64fa670 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1544,37 +1544,23 @@ static inline zend_result build_mime_structure_from_hash(php_curl *ch, zval *zpo /* {{{ Copy a cURL handle along with all of it's preferences */ PHP_FUNCTION(curl_copy_handle) { - php_curl *ch; - CURL *cp; zval *zid; - php_curl *dupch; - zval *postfields; ZEND_PARSE_PARAMETERS_START(1,1) Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce) ZEND_PARSE_PARAMETERS_END(); - ch = Z_CURL_P(zid); - - cp = curl_easy_duphandle(ch->cp); - if (!cp) { + zend_object *new_object = Z_OBJ_P(zid)->handlers->clone_obj(Z_OBJ_P(zid)); + if (EG(exception)) { + if (new_object != NULL) { + OBJ_RELEASE(new_object); + } + zend_clear_exception(); php_error_docref(NULL, E_WARNING, "Cannot duplicate cURL handle"); RETURN_FALSE; } - dupch = init_curl_handle_into_zval(return_value); - dupch->cp = cp; - - _php_setup_easy_copy_handlers(dupch, ch); - - postfields = &ch->postfields; - if (Z_TYPE_P(postfields) != IS_UNDEF) { - if (build_mime_structure_from_hash(dupch, postfields) == FAILURE) { - zval_ptr_dtor(return_value); - php_error_docref(NULL, E_WARNING, "Cannot rebuild mime structure"); - RETURN_FALSE; - } - } + RETURN_OBJ(new_object); } /* }}} */