com php-src: Fixed bug #69316 (Use-after-free in php_curl r elated to CURLOPT_FILE/_INFILE/_WRITEHEADER): e xt/curl/interface.c
ext/curl/tests/bug69316.php t
| From: | Stanislav Malyshev | Date: | Sat, 11 Apr 2015 23:53:21 +0000 |
| Subject: | com php-src: Fixed bug #69316 (Use-after-free in php_curl r elated to CURLOPT_FILE/_INFILE/_WRITEHEADER): e xt/curl/interface.c ext/curl/tests/bug69316.php t |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-86180@lists.php.net to get a copy of this message | ||
Commit: 0ea75af9be8a40836951fc89f723dd5390b8b46f
Author: Stanislav Malyshev <stas@php.net> Sat, 4 Apr 2015 15:58:27 -0700
Parents: 809610f5ea38a83b284e1125d1fff129bdd615e7
Branches: PHP-5.4
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=0ea75af9be8a40836951fc89f723dd5390b8b46f
Log:
Fixed bug #69316 (Use-after-free in php_curl related to CURLOPT_FILE/_INFILE/_WRITEHEADER)
Bugs:
https://bugs.php.net/69316
Changed paths:
M ext/curl/interface.c
A ext/curl/tests/bug69316.phpt
Diff:
diff --git a/ext/curl/interface..c b/ext/curl/interface.c
index 0423f71..7f8f276 100644
--- a/ext/curl/interface.c
+++ b/ext/curl/interface.c
@@ -1051,6 +1051,7 @@ static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the
CURLOPT_WRITEFUNCTION");
length = -1;
} else if (retval_ptr) {
+ _php_curl_verify_handlers(ch, 1 TSRMLS_CC);
if (Z_TYPE_P(retval_ptr) != IS_LONG) {
convert_to_long_ex(&retval_ptr);
}
@@ -1124,6 +1125,7 @@ static size_t curl_progress(void *clientp, double dltotal, double dlnow,
double
if (error == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot call the
CURLOPT_PROGRESSFUNCTION");
} else if (retval_ptr) {
+ _php_curl_verify_handlers(ch, 1 TSRMLS_CC);
if (Z_TYPE_P(retval_ptr) != IS_LONG) {
convert_to_long_ex(&retval_ptr);
}
@@ -1200,6 +1202,7 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
length = CURL_READFUNC_ABORT;
#endif
} else if (retval_ptr) {
+ _php_curl_verify_handlers(ch, 1 TSRMLS_CC);
if (Z_TYPE_P(retval_ptr) == IS_STRING) {
length = MIN((int) (size * nmemb), Z_STRLEN_P(retval_ptr));
memcpy(data, Z_STRVAL_P(retval_ptr), length);
@@ -1274,6 +1277,7 @@ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void
*ctx
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the
CURLOPT_HEADERFUNCTION");
length = -1;
} else if (retval_ptr) {
+ _php_curl_verify_handlers(ch, 1 TSRMLS_CC);
if (Z_TYPE_P(retval_ptr) != IS_LONG) {
convert_to_long_ex(&retval_ptr);
}
diff --git a/ext/curl/tests/bug69316.phpt b/ext/curl/tests/bug69316.phpt
new file mode 100644
index 0000000..2a88eb2
--- /dev/null
+++ b/ext/curl/tests/bug69316.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Bug #69316: Use-after-free in php_curl related to CURLOPT_FILE/_INFILE/_WRITEHEADER
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) exit("skip curl extension not loaded");
+if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) exit("skip
PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined");
+?>
+--FILE--
+<?php
+ function hdr_callback($ch, $data) {
+ // close the stream, causing the FILE structure to be free()'d
+ if($GLOBALS['f_file']) {
+ fclose($GLOBALS['f_file']); $GLOBALS['f_file'] = 0;
+
+ // cause an allocation of approx the same size as a FILE structure, size varies a bit
depending on platform/libc
+ $FILE_size = (PHP_INT_SIZE == 4 ? 0x160 : 0x238);
+ curl_setopt($ch, CURLOPT_COOKIE, str_repeat("a", $FILE_size - 1));
+ }
+ return strlen($data);
+ }
+ $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER');
+
+ $temp_file = dirname(__FILE__) . '/body.tmp';
+ $url = "{$host}/get.php?test=getpost";
+ $ch = curl_init();
+ $f_file = fopen($temp_file, "w") or die("failed to open file\n");
+ curl_setopt($ch, CURLOPT_BUFFERSIZE, 10);
+ curl_setopt($ch, CURLOPT_HEADERFUNCTION, "hdr_callback");
+ curl_setopt($ch, CURLOPT_FILE, $f_file);
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_exec($ch);
+ curl_close($ch);
+?>
+===DONE===
+--CLEAN--
+<?php
+unlink(dirname(__FILE__) . '/body.tmp');
+?>
+--EXPECTF--
+Warning: curl_exec(): CURLOPT_FILE resource has gone away, resetting to default in %s on line %d
+===DONE===