]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
multi: init_do(): check result
authorStefan Eissing <stefan@eissing.org>
Wed, 23 Apr 2025 09:24:45 +0000 (11:24 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 24 Apr 2025 06:43:03 +0000 (08:43 +0200)
Calls to `Curl_init_do()` did not check on result and missed failures to
properly and completely initialize a transfer request.

The main cause of such an init failure is the need to rewind the
READFUNCTION without a SEEKFUNCTION registered. Check the failure to
"rewind" the upload data immediately make test cases 1576 and friends
fail.

Reported-by: Travis Lane
Fixes #17139
Closes #17150

lib/multi.c
lib/url.c
tests/libtest/lib1576.c
tests/mk-bundle.pl

index d2615d3b4c969014ec1a9885b11e180612589557..ddeab7e86726fb955c774187232542494ea98198 100644 (file)
@@ -1560,10 +1560,15 @@ CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
   rc = curl_multi_add_handle(multi, data);
   if(!rc) {
     struct SingleRequest *k = &data->req;
+    CURLcode result;
 
     /* pass in NULL for 'conn' here since we do not want to init the
        connection, only this transfer */
-    Curl_init_do(data, NULL);
+    result = Curl_init_do(data, NULL);
+    if(result) {
+      curl_multi_remove_handle(multi, data);
+      return CURLM_INTERNAL_ERROR;
+    }
 
     /* take this handle to the perform state right away */
     multistate(data, MSTATE_PERFORMING);
index 9d17ce9779a3d9753a46abfc3922d2056380fae0..e47ae6095765688d273a23b68773b3fb0cc69bf4 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -3533,28 +3533,26 @@ static CURLcode create_conn(struct Curl_easy *data,
     /* conn_protocol can only provide "old" protocols */
     data->info.conn_protocol = (conn->handler->protocol) & CURLPROTO_MASK;
     result = conn->handler->connect_it(data, &done);
+    if(result)
+      goto out;
 
     /* Setup a "faked" transfer that will do nothing */
+    Curl_attach_connection(data, conn);
+    result = Curl_cpool_add(data, conn);
     if(!result) {
-      Curl_attach_connection(data, conn);
-      result = Curl_cpool_add(data, conn);
+      /* Setup whatever necessary for a resumed transfer */
+      result = setup_range(data);
       if(!result) {
-        /* Setup whatever necessary for a resumed transfer */
-        result = setup_range(data);
-      }
-
-      if(result) {
-        DEBUGASSERT(conn->handler->done);
-        /* we ignore the return code for the protocol-specific DONE */
-        (void)conn->handler->done(data, result, FALSE);
-        goto out;
+        Curl_xfer_setup_nop(data);
+        result = Curl_init_do(data, conn);
       }
-      Curl_xfer_setup_nop(data);
     }
 
-    /* since we skip do_init() */
-    Curl_init_do(data, conn);
-
+    if(result) {
+      DEBUGASSERT(conn->handler->done);
+      /* we ignore the return code for the protocol-specific DONE */
+      (void)conn->handler->done(data, result, FALSE);
+    }
     goto out;
   }
 #endif
@@ -3704,7 +3702,9 @@ static CURLcode create_conn(struct Curl_easy *data,
   }
 
   /* Setup and init stuff before DO starts, in preparing for the transfer. */
-  Curl_init_do(data, conn);
+  result = Curl_init_do(data, conn);
+  if(result)
+    goto out;
 
   /*
    * Setup whatever necessary for a resumed transfer
index 46952e3eeaa0210aa9a1d22a9c0049d81878200f..a25798824d57b0005c746b971a1f8e75cb0f71ba 100644 (file)
@@ -38,6 +38,15 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream)
   return strlen(testdata);
 }
 
+static int seek_callback(void *ptr, curl_off_t offset, int origin)
+{
+  (void)ptr;
+  (void)offset;
+  if(origin != SEEK_SET)
+    return CURL_SEEKFUNC_FAIL;
+  return CURL_SEEKFUNC_OK;
+}
+
 CURLcode test(char *URL)
 {
   CURLcode res;
@@ -62,6 +71,7 @@ CURLcode test(char *URL)
   test_setopt(curl, CURLOPT_URL, URL);
   test_setopt(curl, CURLOPT_UPLOAD, 1L);
   test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
+  test_setopt(curl, CURLOPT_SEEKFUNCTION, seek_callback);
   test_setopt(curl, CURLOPT_INFILESIZE, (long)strlen(testdata));
 
   test_setopt(curl, CURLOPT_CUSTOMREQUEST, "CURL");
index 5ed28a0807fd7b1f4d5ac750cbd92cb27659073e..6ca51392c7518529a0afc3ada8032b6103c04092 100755 (executable)
@@ -78,6 +78,7 @@ my @reused_symbols = (
     "removeFd",
     "rlim2str",
     "run_thread",
+    "seek_callback",
     "send_ping",
     "showem",
     "store_errmsg",