cURL
Haxx ad
libcurl

curl's project page on SourceForge.net

Sponsors:
Haxx

cURL > Mailing List > Monthly Index > Single Mail

curl-tracker mailing list Archives

[ curl-Bugs-2041827 ] Segfault in http_output_auth w/ FORBID_REUSE (7.18.2)

From: SourceForge.net <noreply_at_sourceforge.net>
Date: Fri, 08 Aug 2008 09:03:45 +0000

Bugs item #2041827, was opened at 2008-08-07 17:40
Message generated for change (Comment added) made by felix-sf191
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=100976&aid=2041827&group_id=976

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: http
Group: crash
Status: Open
Resolution: Works For Me
Priority: 5
Private: No
Submitted By: Felix (felix-sf191)
Assigned to: Daniel Stenberg (bagder)
Summary: Segfault in http_output_auth w/ FORBID_REUSE (7.18.2)

Initial Comment:
I use the PHP API of libcurl, but the segfaults happen in libcurl itself. The situation is a bit complicated, but I try to include all information I have.

In my PHP application I do not receive a segmentation fault but a sig abort sent from glibc:

*** glibc detected *** double free or corruption (fasttop): 0x0879d1a0 ***

For my application is quite big I have tried to isolate the problem with a simpler script. Now I get segfaults instead of the sigabort, but that might be caused by the same problem.

I use the multi api to perform two requests to the same server at once. One of the requests receives a 200 response directly, the other has to follow one redirect to get the 200. Everything works fine until I set CURLOPT_FORBID_REUSE (= true). Then every now and then (more than 1 out of 10) the program segfaults with a backtrace ending in http_output_auth:

-------------------------------
#0 0xb7d57cea in http_output_auth () from libcurl.so.4
#1 0xb7d590bb in Curl_http () from libcurl.so.4
#2 0xb7d6587d in Curl_do () from lib/libcurl.so.4
#3 0xb7d74d8e in multi_runsingle () from libcurl.so.4
#4 0xb7d75839 in curl_multi_perform () from libcurl.so.4
#5 0x080b3e12 in zif_curl_multi_exec ()
#6 0x0838885f in zend_do_fcall_common_helper_SPEC ()
#7 0x083875d8 in execute ()
#8 0x08363170 in zend_execute_scripts ()
#9 0x08318ac2 in php_execute_script ()
#10 0x083f0494 in main ()
-------------------------------

As the client PHP script I have used the curl_multi_exec_example from http://de.php.net/manual/en/function.curl-multi-exec.php. Besides the URLs the only significant change is that I have CURLOPT_FORBID_REUSE set.
-------------------------------
$url = "http://example.com/redir.php";
$url2 = $url ."?uri=". urlencode($url);

// create both cURL resources
$ch1 = curl_init();
$ch2 = curl_init();

// set URL and other appropriate options
curl_setopt($ch1, CURLOPT_URL, $url);
curl_setopt($ch2, CURLOPT_URL, $url2);

curl_setopt($ch1, CURLOPT_FORBID_REUSE, true);
curl_setopt($ch2, CURLOPT_FORBID_REUSE, true);

curl_setopt($ch2, CURLOPT_FOLLOWLOCATION, true);

/* from here on no changes to the example from http://de.php.net/manual/en/function.curl-multi-exec.php */

//create the multiple cURL handle
$mh = curl_multi_init();

//add the two handles
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);

$active = null;
//execute the handles
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($mh) != -1) {
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}

//close the handles
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
echo "\n";
-------------------------------

As the server side script you can use s/th like this:

-------------------------------
if (!empty($_GET['uri'])) {
    header("Location: ". $_GET['uri']);
} else {
    echo "done";
}
-------------------------------

I don't think it is http_output_auth's fault. That is probably just the first place where the error occurs.

The segfaults disapper when either
 * both requests are redirects
 * the two requests connect to different servers
 * CURLOPT_FORBID_REUSE is set to FALSE

I use PHP-5.2.6, libcurl-7.18.2 on Debian etch.

----------------------------------------------------------------------

>Comment By: Felix (felix-sf191)
Date: 2008-08-08 11:03

Message:
Logged In: YES
user_id=2099045
Originator: YES

I have tried your c program on my machine and I still get the segmentation
fault every few runs:

-------------------------------------------
[New Thread -1211963712 (LWP 29199)]
* About to connect() to fh.devel port 7825 (#0)
* Trying 172.31.51.105... * connected
* Connected to fh.devel (172.31.51.105) port 7825 (#0)
* About to connect() to fh.devel port 7825 (#1)
* Trying 172.31.51.105... * connected
* Connected to fh.devel (172.31.51.105) port 7825 (#1)
> GET /tests/redir.php HTTP/1.1
Host: fh.devel:7825
Accept: */*

> GET /tests/redir.php?uri=redir.php HTTP/1.1
Host: fh.devel7825
Accept: */*

< HTTP/1.1 302 Found
< Date: Fri, 08 Aug 2008 07:56:01 GMT
< Server: Apache
< Location: http://fh.devel:7825/tests/redir.php
< Content-Length: 0
< Content-Type: text/html
<
* Expire cleared
* Closing connection #1
* Issue another request to this URL:
'http://fh.devel:7825/tests/redir.php'
< HTTP/1.1 200 OK
< Date: Fri, 08 Aug 2008 07:56:01 GMT
< Server: Apache
< Content-Length: 4
< Content-Type: text/html
<
* Re-using existing connection! (#0) with host fh.devel
* Connected to fh.devel (172.31.51.105) port 7825 (#0)
* Expire cleared
* Closing connection #0

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1211963712 (LWP 29199)]
0xb7f1aa8a in http_output_auth () from libcurl.so.4
(gdb) bt
#0 0xb7f1aa8a in http_output_auth () from libcurl.so.4
#1 0xb7f1be5b in Curl_http () from libcurl.so.4
#2 0xb7f2890d in Curl_do () from libcurl.so.4
#3 0xb7f3786e in multi_runsingle () from libcurl.so.4
#4 0xb7f38319 in curl_multi_perform () from libcurl.so.4
#5 0x080487ba in runner ()
#6 0x080488ed in main ()
-------------------------------------------

I have build your program in a Debian Vserver with gcc (GCC) 4.1.2
20061115 (prerelease) (Debian 4.1.1-21)
using the command line:
gcc `curl-config --cflags` `curl-config --libs` test-2041827.c

On a CentOS 5.2 with gcc version 4.1.2 20071124 (Red Hat 4.1.2-42) I get
the sigabort that I originally got:
----------------------------------------------
Program received signal SIGABRT, Aborted.
[Switching to Thread -1212470720 (LWP 24705)]
0xffffe410 in __kernel_vsyscall ()
(gdb) bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0xb7dcad20 in raise () from /lib/libc.so.6
#2 0xb7dcc631 in abort () from /lib/libc.so.6
#3 0xb7e02e6b in __libc_message () from /lib/libc.so.6
#4 0xb7e0ab16 in _int_free () from /lib/libc.so.6
#5 0xb7e0e070 in free () from /lib/libc.so.6
#6 0xb7f048b2 in Curl_safefree (ptr=0x806d9d8) at url.c:283
#7 0xb7efbe51 in Curl_http (conn=0x806cd00, done=0xbf8fa068) at
http.c:2086
#8 0xb7f0885c in Curl_do (connp=0x806c9ec, done=0xbf8fa068) at
url.c:4578
#9 0xb7f19eaf in multi_runsingle (multi=0x8050170, easy=0x806c9e0) at
multi.c:1102
#10 0xb7f1a907 in curl_multi_perform (multi_handle=0x8050170,
running_handles=0xbf8fa274) at multi.c:1460
#11 0x0804878a in runner (multi_handle=0x8050170) at test-2041827.c:52
#12 0x080488bd in main () at test-2041827.c:96
---------------------------------------------------------

It is interesting how the verbose output differs when the program works
and when it fails.

Working version:
------------------------------------------
* About to connect() to fh.devel port 7825 (#0)
* Trying 172.31.51.105... * connected
* Connected to fh.devel (172.31.51.105) port 7825 (#0)
* About to connect() to fh.devel port 7825 (#1)
* Trying 172.31.51.105... * connected
* Connected to fh.devel (172.31.51.105) port 7825 (#1)
> GET /tests/redir.php HTTP/1.1
Host: fh.devel:7825
Accept: */*

> GET /tests/redir.php?uri=http://fh.devel:7825/tests/redir.php HTTP/1.1
Host: fh.devel:7825
Accept: */*

< HTTP/1.1 200 OK
< Date: Fri, 08 Aug 2008 08:37:09 GMT
< Server: Apache
< Content-Length: 4
< Content-Type: text/html
<
* Closing connection #0
< HTTP/1.1 302 Found
< Date: Fri, 08 Aug 2008 08:37:09 GMT
< Server: Apache
< Location: http://fh.devel:7825/tests/redir.php
< Content-Length: 0
< Content-Type: text/html
<
* Closing connection #1
* Issue another request to this URL:
'http://fh.devel:7825/tests/redir.php'
* About to connect() to fh.devel port 7825 (#0)
* Trying 172.31.51.105... * connected
* Connected to fh.devel (172.31.51.105) port 7825 (#0)
> GET /tests/redir.php HTTP/1.1
Host: fh.devel:7825
Accept: */*

< HTTP/1.1 200 OK
< Date: Fri, 08 Aug 2008 08:37:09 GMT
< Server: Apache
< Content-Length: 4
< Content-Type: text/html
<
* Closing connection #0
------------------------------------------
The direct 200 is returned first. Then the 302 returns. _Both_ connections
are closed. To follow the redirect another connection has to be opened.

Now the segfaulting/sigaborting version:
------------------------------------------
* About to connect() to fh.devel port 7825 (#0)
* Trying 172.31.51.105... * connected
* Connected to fh.devel (172.31.51.105) port 7825 (#0)
* About to connect() to fh.devel port 7825 (#1)
* Trying 172.31.51.105... * connected
* Connected to fh.devel (172.31.51.105) port 7825 (#1)
> GET /tests/redir.php HTTP/1.1
Host: fh.devel:7825
Accept: */*

> GET /tests/redir.php?uri=http://fh.devel:7825/tests/redir.php HTTP/1.1
Host: fh.devel:7825
Accept: */*

< HTTP/1.1 302 Found
< Date: Fri, 08 Aug 2008 08:41:19 GMT
< Server: Apache
< Location: http://fh.devel:7825/tests/redir.php
< Content-Length: 0
< Content-Type: text/html
<
* Expire cleared
* Closing connection #1
* Issue another request to this URL:
'http://fh.devel:7825/tests/redir.php'
< HTTP/1.1 200 OK
< Date: Fri, 08 Aug 2008 08:41:19 GMT
< Server: Apache
< Content-Length: 4
< Content-Type: text/html
<
* Re-using existing connection! (#0) with host fh.devel
* Connected to fh.devel (172.31.51.105) port 7825 (#0)
* Expire cleared
* Closing connection #0
segmentation fault
------------------------------------------

In this case the 302 answer comes first. That seems to lead to a different
behaviour. The connection of the redirected request is closed. When the
direct 200 arrives, that sane connection is reused to follow the redirect:
"Re-using existing connection! (#0)". Every time this message occurs, the
program fails.

----------------------------------------------------------------------

Comment By: Daniel Stenberg (bagder)
Date: 2008-08-08 00:14

Message:
Logged In: YES
user_id=1110
Originator: NO

I wrote up a version of that program in plain C using libcurl directly,
and I cannot seem to repeat any crash out of it. See the attached file for
the exact code I used.

File Added: test-2041827.c

----------------------------------------------------------------------

You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=100976&aid=2041827&group_id=976
Received on 2008-08-08

These mail archives are generated by hypermail.

donate! Page updated November 12, 2010.
web site info

File upload with ASP.NET