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



      

Attachment: 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

Reply via email to