From a80f0b515a22bde29b6fffbf26ae74025822bbdf Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 10 Nov 2024 14:04:50 +0100 Subject: [PATCH] Fix various memory leaks in curl mime handling Closes GH-16745. --- NEWS | 3 +++ ext/curl/interface.c | 39 ++++++++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/NEWS b/NEWS index cfddddad95cbc..c09900ebd6b8d 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,9 @@ PHP NEWS (nielsdos) . Fix is_zend_ptr() huge block comparison. (nielsdos) +- Curl: + . Fix various memory leaks in curl mime handling. (nielsdos) + - FPM: . Fixed GH-16432 (PHP-FPM 8.2 SIGSEGV in fpm_get_status). (Jakub Zelenka) diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 4884ddc8228a1..6798a384c7785 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1381,7 +1381,7 @@ static inline zend_result build_mime_structure_from_hash(php_curl *ch, zval *zpo postval = Z_STR_P(prop); if (php_check_open_basedir(ZSTR_VAL(postval))) { - return FAILURE; + goto out_string; } prop = zend_read_property(curl_CURLFile_class, Z_OBJ_P(current), "mime", sizeof("mime")-1, 0, &rv); @@ -1407,15 +1407,18 @@ static inline zend_result build_mime_structure_from_hash(php_curl *ch, zval *zpo seekfunc = NULL; } + part = curl_mime_addpart(mime); + if (part == NULL) { + if (stream) { + php_stream_close(stream); + } + goto out_string; + } + cb_arg = emalloc(sizeof *cb_arg); cb_arg->filename = zend_string_copy(postval); cb_arg->stream = stream; - part = curl_mime_addpart(mime); - if (part == NULL) { - zend_string_release_ex(string_key, 0); - return FAILURE; - } if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK || (form_error = curl_mime_data_cb(part, filesize, read_cb, seekfunc, free_cb, cb_arg)) != CURLE_OK || (form_error = curl_mime_filename(part, filename ? filename : ZSTR_VAL(postval))) != CURLE_OK @@ -1449,8 +1452,7 @@ static inline zend_result build_mime_structure_from_hash(php_curl *ch, zval *zpo prop = zend_read_property(curl_CURLStringFile_class, Z_OBJ_P(current), "postname", sizeof("postname")-1, 0, &rv); if (EG(exception)) { - zend_string_release_ex(string_key, 0); - return FAILURE; + goto out_string; } ZVAL_DEREF(prop); ZEND_ASSERT(Z_TYPE_P(prop) == IS_STRING); @@ -1459,8 +1461,7 @@ static inline zend_result build_mime_structure_from_hash(php_curl *ch, zval *zpo prop = zend_read_property(curl_CURLStringFile_class, Z_OBJ_P(current), "mime", sizeof("mime")-1, 0, &rv); if (EG(exception)) { - zend_string_release_ex(string_key, 0); - return FAILURE; + goto out_string; } ZVAL_DEREF(prop); ZEND_ASSERT(Z_TYPE_P(prop) == IS_STRING); @@ -1469,8 +1470,7 @@ static inline zend_result build_mime_structure_from_hash(php_curl *ch, zval *zpo prop = zend_read_property(curl_CURLStringFile_class, Z_OBJ_P(current), "data", sizeof("data")-1, 0, &rv); if (EG(exception)) { - zend_string_release_ex(string_key, 0); - return FAILURE; + goto out_string; } ZVAL_DEREF(prop); ZEND_ASSERT(Z_TYPE_P(prop) == IS_STRING); @@ -1483,8 +1483,7 @@ static inline zend_result build_mime_structure_from_hash(php_curl *ch, zval *zpo part = curl_mime_addpart(mime); if (part == NULL) { - zend_string_release_ex(string_key, 0); - return FAILURE; + goto out_string; } if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK || (form_error = curl_mime_data(part, ZSTR_VAL(postval), ZSTR_LEN(postval))) != CURLE_OK @@ -1540,7 +1539,7 @@ static inline zend_result build_mime_structure_from_hash(php_curl *ch, zval *zpo SAVE_CURL_ERROR(ch, error); if (error != CURLE_OK) { - return FAILURE; + goto out_mime; } if ((*ch->clone) == 1) { @@ -1556,6 +1555,16 @@ static inline zend_result build_mime_structure_from_hash(php_curl *ch, zval *zpo SAVE_CURL_ERROR(ch, error); return error == CURLE_OK ? SUCCESS : FAILURE; + +out_string: + zend_string_release_ex(string_key, false); +out_mime: +#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */ + curl_mime_free(mime); +#else + curl_formfree(first); +#endif + return FAILURE; } /* }}} */