Hi All, I spent some time debugging the curl code while Kamil and I were debugging this issue and I think I found out what is going on. Someplace in the code it looks like a data structure was released twice. So I looked in curl_nss_connect and saw that the model structure will be freed twice if the handshake fails.
At line 939:
PRFileDesc *model = NULL;
At line 1201:
PR_Close(model); /* We don't need this any more */
Then at line 1214 if SSL_ForceHandshakeWithTimeout fails, goto error is called
and at line 1267:
if(model)
PR_Close(model);
I created a patch that sets model to NULL around line 1201 and that seems to
fix my crash. See below:
*** curl-7.19.6/lib/nss.c Fri Jul 31 20:15:35 2009
--- /tmp/nss.c Wed Nov 11 17:52:27 2009
***************
*** 1184,1190 ****
--- 1184,1192 ----
connssl->handle = SSL_ImportFD(model, connssl->handle);
if(!connssl->handle)
goto error;
+
PR_Close(model); /* We don't need this any more */
+ model = NULL;
/* This is the password associated with the cert that we're using */
if (data->set.str[STRING_KEY_PASSWD]) {
It looks at some point the handshake failed and between the first and the
second close was called someone else was using the NSS socket stucture and the
fd element was released.
Patch it attached.
Thanks,
Kevin
________________________________
From: Kamil Dudka <[email protected]>
To: Daniel Stenberg <[email protected]>
Cc: [email protected]
Sent: Tue, November 10, 2009 4:58:23 PM
Subject: SSL_ForceHandshake may return PR_ERROR_WOULD_BLOCK [was Re: Seg
fault...]
On Tuesday 10 of November 2009 21:34:13 Kamil Dudka wrote:
> We've figured out with Kevin there are actually two bugs taking place:
>
> https://bugzilla.redhat.com/534115
> https://bugzilla.redhat.com/534176
>
> Both of them are assigned to nss for now...
While investigating the issue I spotted another interesting comment before
SSL_ForceHandshake():
/* Try to make progress on an SSL handshake by attempting to read the
** next handshake from the peer, and sending any responses.
** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK if it cannot
** read the next handshake from the underlying socket.
** For SSLv2, returns when handshake is complete or fatal error occurs.
** For SSLv3, returns when handshake is complete, or application data has
** arrived that must be taken by application before handshake can continue,
** or a fatal error occurs.
** Application should use handshake completion callback to tell which.
*/
This means we should check the return value for PR_ERROR_WOULD_BLOCK and
eventually block when doing connection in the blocking mode, or am I missing
anyting?
Kamil
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
curl-7.19.6-modelfree.patch
Description: Binary data
------------------------------------------------------------------- List admin: http://cool.haxx.se/list/listinfo/curl-library Etiquette: http://curl.haxx.se/mail/etiquette.html
