]> granicus.if.org Git - curl/commitdiff
- Andre Guibert de Bruet pointed out a missing return code check for a
authorDaniel Stenberg <daniel@haxx.se>
Fri, 21 Aug 2009 12:01:36 +0000 (12:01 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 21 Aug 2009 12:01:36 +0000 (12:01 +0000)
  strdup() that could lead to segfault if it returned NULL. I extended his
  suggest patch to now have Curl_retry_request() return a regular return code
  and better check that.

CHANGES
RELEASE-NOTES
lib/multi.c
lib/transfer.c
lib/transfer.h

diff --git a/CHANGES b/CHANGES
index 650a36f7becac715bcdf262be29a3148ef25f9e7..eccb1db196753b5afecad2fbd9ba44f1f5668d62 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,11 @@
                                   Changelog
 
 Daniel Stenberg (21 Aug 2009)
+- Andre Guibert de Bruet pointed out a missing return code check for a
+  strdup() that could lead to segfault if it returned NULL. I extended his
+  suggest patch to now have Curl_retry_request() return a regular return code
+  and better check that.
+
 - Lots of good work by Krister Johansen, mostly related to pipelining:
 
   Fix SIGSEGV on free'd easy_conn when pipe unexpectedly breaks
index 5af32e16a1fca31795dcf30652cb307ce8bb9d84..77401bbe54aaea55394b6a06fd03227137011bd1 100644 (file)
@@ -18,6 +18,7 @@ This release includes the following bugfixes:
  o SIGSEGV when pipelined pipe unexpectedly breaks
  o data corruption issue with re-connected transfers
  o use after free if we're completed but easy_conn not NULL (pipelined)
+ o missing strdup() return code check
 
 This release includes the following known bugs:
 
@@ -26,6 +27,6 @@ This release includes the following known bugs:
 This release would not have looked like this without help, code, reports and
 advice from friends like these:
 
- Karl Moerder, Kamil Dudka, Krister Johansen,
+ Karl Moerder, Kamil Dudka, Krister Johansen, Andre Guibert de Bruet
 
         Thanks! (and sorry if I forgot to mention someone)
index 1099b525dba8530201b94e9fe824b4492ce416a4..686372ad169464641c0d310e82f614ba65e3f9a9 100644 (file)
@@ -1183,7 +1183,16 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
           char *newurl;
           followtype follow=FOLLOW_NONE;
           CURLcode drc;
-          bool retry = Curl_retry_request(easy->easy_conn, &newurl);
+          bool retry = FALSE;
+
+          drc = Curl_retry_request(easy->easy_conn, &newurl);
+          if(drc) {
+            /* a failure here pretty much implies an out of memory */
+            easy->result = drc;
+            disconnect_conn = TRUE;
+          }
+          else
+            retry = newurl?TRUE:FALSE;
 
           Curl_posttransfer(easy->easy_handle);
           drc = Curl_done(&easy->easy_conn, easy->result, FALSE);
@@ -1370,9 +1379,13 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       }
       else if(TRUE == done) {
         char *newurl;
-        bool retry = Curl_retry_request(easy->easy_conn, &newurl);
+        bool retry = FALSE;
         followtype follow=FOLLOW_NONE;
 
+        easy->result = Curl_retry_request(easy->easy_conn, &newurl);
+        if(!easy->result)
+          retry = newurl?TRUE:FALSE;
+
         /* call this even if the readwrite function returned error */
         Curl_posttransfer(easy->easy_handle);
 
@@ -1406,7 +1419,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
             multistate(easy, CURLM_STATE_CONNECT);
             result = CURLM_CALL_MULTI_PERFORM;
           }
-          else
+          else if(newurl)
             /* Since we "took it", we are in charge of freeing this on
                failure */
             free(newurl);
index e5ba279d0f3aa0ba0359728dc9be217e9e7ae950..5bd742f47e3464ee9cc69bf5be65921aa6bbe8e7 100644 (file)
@@ -2550,19 +2550,20 @@ Curl_reconnect_request(struct connectdata **connp)
   return result;
 }
 
-/* Returns TRUE and sets '*url' if a request retry is wanted.
+/* Returns CURLE_OK *and* sets '*url' if a request retry is wanted.
 
    NOTE: that the *url is malloc()ed. */
-bool Curl_retry_request(struct connectdata *conn,
-                        char **url)
+CURLcode Curl_retry_request(struct connectdata *conn,
+                            char **url)
 {
-  bool retry = FALSE;
   struct SessionHandle *data = conn->data;
 
+  *url = NULL;
+
   /* if we're talking upload, we can't do the checks below, unless the protocol
      is HTTP as when uploading over HTTP we will still get a response */
   if(data->set.upload && !(conn->protocol&PROT_HTTP))
-    return retry;
+    return CURLE_OK;
 
   if((data->req.bytecount +
       data->req.headerbytecount == 0) &&
@@ -2574,6 +2575,8 @@ bool Curl_retry_request(struct connectdata *conn,
        it again. Bad luck. Retry the same request on a fresh connect! */
     infof(conn->data, "Connection died, retrying a fresh connect\n");
     *url = strdup(conn->data->change.url);
+    if(!*url)
+      return CURLE_OUT_OF_MEMORY;
 
     conn->bits.close = TRUE; /* close this connection */
     conn->bits.retry = TRUE; /* mark this as a connection we're about
@@ -2581,10 +2584,8 @@ bool Curl_retry_request(struct connectdata *conn,
                                 prevent i.e HTTP transfers to return
                                 error just because nothing has been
                                 transfered! */
-    retry = TRUE;
   }
-
-  return retry;
+  return CURLE_OK;
 }
 
 /*
@@ -2629,7 +2630,12 @@ CURLcode Curl_perform(struct SessionHandle *data)
       if(res == CURLE_OK) {
         res = Transfer(conn); /* now fetch that URL please */
         if((res == CURLE_OK) || (res == CURLE_RECV_ERROR)) {
-          bool retry = Curl_retry_request(conn, &newurl);
+          bool retry = FALSE;
+          CURLcode rc = Curl_retry_request(conn, &newurl);
+          if(rc)
+            res = rc;
+          else
+            retry = newurl?TRUE:FALSE;
 
           if(retry) {
             res = CURLE_OK;
index 4b39faa18883bf5a09dbdfd0d4a85f698c132c12..a9b1cd3700ba895df240a7ab72c08b50febc8ce2 100644 (file)
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -47,7 +47,7 @@ int Curl_single_getsock(const struct connectdata *conn,
 CURLcode Curl_readrewind(struct connectdata *conn);
 CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
 CURLcode Curl_reconnect_request(struct connectdata **connp);
-bool Curl_retry_request(struct connectdata *conn, char **url);
+CURLcode Curl_retry_request(struct connectdata *conn, char **url);
 
 /* This sets up a forthcoming transfer */
 CURLcode