php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #52827 cURL leaks handle and causes assertion error (CURLOPT_STDERR)
Submitted: 2010-09-13 16:55 UTC Modified: 2010-09-14 12:59 UTC
From: cataphract@php.net Assigned: aharvey
Status: Closed Package: cURL related
PHP Version: 5.3.3 OS: Debian Lenny x64; Windows 7 x64
Private report: No CVE-ID:
 [2010-09-13 16:55 UTC] cataphract@php.net
Description:
------------
curl_setopt, when given a stream with CURLOPT_STDERR, stores the zval* and increments both the refcount of the zval* and of the resource.

Only the refcount of the zval should be incremented.

Additionally, due to a flaw in the streams API, this leak results in an assertion error. The reason is that on shutdown the unexposed/leaked resources are destroyed in reverse order, so the encapsulated STDIO stream is destroyed first and when the TEMP stream is destroyed, it then tries to close the encapsulated STDIO steam again. I will submit this as a separate bug report.

Test script:
---------------
<?php
$s = fopen('php://temp/maxmemory=1024','wb+');

/* force conversion of inner stream to STDIO.
 * This is not necessary in Windows because the
 * cast to a FILE* handle in curl_setopt already
 * forces the conversion in that platform. The
 * reason for this conversion is that the memory
 * stream has an ugly but working mechanism to
 * prevent being double freed when it's encapsulated,
 * while STDIO streams don't. */
$i = 0;
while ($i++ < 5000) {
fwrite($s, str_repeat('a',1024));
}
$handle=curl_init('http://www.example.com');
curl_setopt($handle, CURLOPT_STDERR, $s);

Expected result:
----------------
No output.

Actual result:
--------------
(with stream debug)

stream_alloc: TEMP:0x12a61b0 persistent=(null)
stream_alloc: MEMORY:0x12a6488 persistent=(null)
stream_alloc: STDIO:0x12a6f90 persistent=(null)
stream_free: MEMORY:0x12a6488[(null)] in_free=0 opts=00000003
stream_free: MEMORY:0x12a6488[(null)] preserve_handle=0 release_cast=1 remove_rs  rc=1
stream_free: MEMORY:0x12a6488[(null)] in_free=1 opts=0000000b
stream_free: STDIO:0x12a6f90[/tmp/phpghmjqQ] in_free=0 opts=0000000b
stream_free: STDIO:0x12a6f90[/tmp/phpghmjqQ] preserve_handle=0 release_cast=1 re  move_rsrc=1
/tmp/php-5.3.3/main/streams/streams.c(400) : Stream of type 'STDIO' 0x12a6f90 (p  ath:/tmp/phpghmjqQ) was not closed
stream_free: TEMP:0x12a61b0[php://temp/maxmemory=1024] in_free=0 opts=0000000b
stream_free: TEMP:0x12a61b0[php://temp/maxmemory=1024] preserve_handle=0 release  _cast=1 remove_rsrc=1
php: /tmp/php-5.3.3/main/streams/plain_wrapper.c:434: php_stdiop_flush: Assertio  n `data != ((void *)0)' failed.
Aborted



#0  0x00007f74b5a22ed5 in raise () from /lib/libc.so.6
#1  0x00007f74b5a243f3 in abort () from /lib/libc.so.6
#2  0x00007f74b5a1bdc9 in __assert_fail () from /lib/libc.so.6
#3  0x000000000076129e in php_stdiop_flush (stream=0x1049dc8)
    at /tmp/php-5.3.3/main/streams/plain_wrapper.c:434
#4  0x00000000007596dd in _php_stream_flush (stream=0x1049dc8, closing=0)
    at /tmp/php-5.3.3/main/streams/streams.c:1050
#5  0x000000000075df57 in php_stream_temp_flush (stream=0x1049050)
    at /tmp/php-5.3.3/main/streams/memory.c:440
#6  0x00000000007596dd in _php_stream_flush (stream=0x1049050, closing=1)
    at /tmp/php-5.3.3/main/streams/streams.c:1050
#7  0x0000000000757b4d in _php_stream_free (stream=0x1049050, close_options=11)
    at /tmp/php-5.3.3/main/streams/streams.c:331
#8  0x000000000075a831 in stream_resource_regular_dtor (rsrc=0x104ab48)
    at /tmp/php-5.3.3/main/streams/streams.c:1426
#9  0x00000000007c4f9e in list_entry_destructor (ptr=0x104ab48)
    at /tmp/php-5.3.3/Zend/zend_list.c:184
#10 0x00000000007c249d in zend_hash_apply_deleter (ht=0xe0c650, p=0x1049198)
    at /tmp/php-5.3.3/Zend/zend_hash.c:611
#11 0x00000000007c25ff in zend_hash_graceful_reverse_destroy (ht=0xe0c650)
    at /tmp/php-5.3.3/Zend/zend_hash.c:646
#12 0x00000000007c510f in zend_destroy_rsrc_list (ht=0xe0c650)
    at /tmp/php-5.3.3/Zend/zend_list.c:240
#13 0x00000000007b1549 in zend_deactivate () at /tmp/php-5.3.3/Zend/zend.c:896
#14 0x000000000073e71b in php_request_shutdown (dummy=0x0)
    at /tmp/php-5.3.3/main/main.c:1633
#15 0x0000000000899a12 in main (argc=2, argv=0x7fffea5acfa8)
    at /tmp/php-5.3.3/sapi/cli/php_cli.c:1373


Patches

curlopt_stderr_with_test (last revision 2010-09-13 18:49 UTC) by cataphract@php.net)
curlopt_stderr (last revision 2010-09-13 14:56 UTC) by cataphract@php.net)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-09-13 16:56 UTC] cataphract@php.net
The following patch has been added/updated:

Patch Name: curlopt_stderr
Revision:   1284389761
URL:        http://bugs.php.net/patch-display.php?bug=52827&patch=curlopt_stderr&revision=1284389761
 [2010-09-13 16:57 UTC] cataphract@php.net
-Operating System: Ubuntu 10.4 x64; Windows 7 x64 +Operating System: Debian Lenny x64; Windows 7 x64
 [2010-09-13 20:49 UTC] cataphract@php.net
The following patch has been added/updated:

Patch Name: curlopt_stderr_with_test
Revision:   1284403798
URL:        http://bugs.php.net/patch-display.php?bug=52827&patch=curlopt_stderr_with_test&revision=1284403798
 [2010-09-14 12:48 UTC] aharvey@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: aharvey
 [2010-09-14 12:59 UTC] aharvey@php.net
Automatic comment from SVN on behalf of aharvey
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=303361
Log: Fix bug #52827 (cURL leaks handle and causes assertion error (CURLOPT_STDERR)).
Patch by Gustavo.
 [2010-09-14 12:59 UTC] aharvey@php.net
-Status: Assigned +Status: Closed
 [2010-09-14 12:59 UTC] aharvey@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

Thanks Gustavo!
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 25 07:02:14 2014 UTC