]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
socks: do_SOCKS5: Fix invalid buffer content on short send
authorAmmar Faizi <ammarfaizi2@gnuweeb.org>
Wed, 16 Jul 2025 13:22:43 +0000 (20:22 +0700)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 17 Jul 2025 22:38:15 +0000 (00:38 +0200)
Ahmad Gani intercepts the sendto syscall to simulate short send, but
curl incorrectly handles it. It keeps resending the version:

  sendto(4, "\x05", 1, MSG_NOSIGNAL, NULL, 0) = 1
  sendto(4, "\x05", 1, MSG_NOSIGNAL, NULL, 0) = 1

Don't restart the buffer in the `CONNECT_SOCKS_INIT` case if
`sx->outstanding` is not zero. It should continue sending the
advanced buffer.

Fixes #17942
Reported-by: Ahmad Gani <reyuki@gnuweeb.org>
Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
Closes #17943

lib/socks.c

index 7d25ef52087affc5b9cb002891c7af88cdd6cab8..023696c4612e37f758b765d8484f76749a090d24 100644 (file)
@@ -591,20 +591,23 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf,
       allow_gssapi = TRUE;
 #endif
 
-    idx = 0;
-    socksreq[idx++] = 5;   /* version */
-    idx++;                 /* number of authentication methods */
-    socksreq[idx++] = 0;   /* no authentication */
-    if(allow_gssapi)
-      socksreq[idx++] = 1; /* GSS-API */
-    if(sx->proxy_user)
-      socksreq[idx++] = 2; /* username/password */
-    /* write the number of authentication methods */
-    socksreq[1] = (unsigned char) (idx - 2);
+    if(!sx->outstanding) {
+      idx = 0;
+      socksreq[idx++] = 5;   /* version */
+      idx++;                 /* number of authentication methods */
+      socksreq[idx++] = 0;   /* no authentication */
+      if(allow_gssapi)
+        socksreq[idx++] = 1; /* GSS-API */
+      if(sx->proxy_user)
+        socksreq[idx++] = 2; /* username/password */
+      /* write the number of authentication methods */
+      socksreq[1] = (unsigned char) (idx - 2);
+
+      sx->outp = socksreq;
+      DEBUGASSERT(idx <= sizeof(sx->buffer));
+      sx->outstanding = idx;
+    }
 
-    sx->outp = socksreq;
-    DEBUGASSERT(idx <= sizeof(sx->buffer));
-    sx->outstanding = idx;
     presult = socks_state_send(cf, sx, data, CURLPX_SEND_CONNECT,
                                "initial SOCKS5 request");
     if(CURLPX_OK != presult)