Skip to content

Commit beb8d76

Browse files
committed
Merge branch 'PHP-8.6'
* PHP-8.6: curl: Fix UAF on clone due to callback data pointer mismatch
2 parents fb7fb98 + f817620 commit beb8d76

2 files changed

Lines changed: 35 additions & 2 deletions

File tree

‎ext/curl/interface.c‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,10 @@ static int curl_ssh_hostkeyfunction(void *clientp, int keytype, const char *key,
796796
php_curl *ch = (php_curl *)clientp;
797797
int rval = CURLKHMATCH_MISMATCH; /* cancel connection in case of an exception */
798798

799+
if (!ZEND_FCC_INITIALIZED(ch->handlers.sshhostkey)) {
800+
return rval;
801+
}
802+
799803
#if PHP_CURL_DEBUG
800804
fprintf(stderr, "curl_ssh_hostkeyfunction() called\n");
801805
fprintf(stderr, "clientp = %p, keytype = %d, key = %s, keylen = %zu\n", clientp, keytype, key, keylen);
@@ -1274,8 +1278,11 @@ static void php_curl_copy_fcc_with_option(php_curl *ch, CURLoption option, zend_
12741278
{
12751279
if (ZEND_FCC_INITIALIZED(*source_fcc)) {
12761280
zend_fcc_dup(target_fcc, source_fcc);
1277-
curl_easy_setopt(ch->cp, option, (void *) ch);
12781281
}
1282+
1283+
/* The callback data (i.e. pointer to the curl handle) stays even if a user callback
1284+
* is reset to NULL. Ensure the data pointer always points to the new handle. */
1285+
curl_easy_setopt(ch->cp, option, (void *) ch);
12791286
}
12801287

12811288
void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
@@ -1319,7 +1326,6 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
13191326
curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch);
13201327
curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch);
13211328
curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch);
1322-
curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, (void *) ch);
13231329

13241330
php_curl_copy_fcc_with_option(ch, CURLOPT_SEEKDATA, &ch->handlers.seek, &source->handlers.seek);
13251331
php_curl_copy_fcc_with_option(ch, CURLOPT_PROGRESSDATA, &ch->handlers.progress, &source->handlers.progress);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
Cloning a curl handle whose CURLOPT_PROGRESSFUNCTION was reset to null must not reference the source handle
3+
--EXTENSIONS--
4+
curl
5+
--FILE--
6+
<?php
7+
$srcfile = __DIR__ . '/curl_copy_handle_progress_null_uaf.txt';
8+
file_put_contents($srcfile, "Test.");
9+
10+
$ch1 = curl_init();
11+
curl_setopt($ch1, CURLOPT_URL, "file://" . $srcfile);
12+
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
13+
curl_setopt($ch1, CURLOPT_NOPROGRESS, false);
14+
curl_setopt($ch1, CURLOPT_PROGRESSFUNCTION, fn() => 0);
15+
curl_setopt($ch1, CURLOPT_PROGRESSFUNCTION, null);
16+
17+
$ch2 = clone $ch1;
18+
unset($ch1);
19+
20+
var_dump(curl_exec($ch2));
21+
?>
22+
--CLEAN--
23+
<?php
24+
@unlink(__DIR__ . '/curl_copy_handle_progress_null_uaf.txt');
25+
?>
26+
--EXPECT--
27+
string(5) "Test."

0 commit comments

Comments
 (0)