]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
cf-socket: error if address can't be copied
authorJay Satiro <raysatiro@yahoo.com>
Thu, 19 Dec 2024 22:12:02 +0000 (17:12 -0500)
committerJay Satiro <raysatiro@yahoo.com>
Sun, 22 Dec 2024 08:12:35 +0000 (03:12 -0500)
- When converting Curl_addrinfo to Curl_sockaddr_ex, if the address
  length is too large then return error CURLE_TOO_LARGE.

Prior to this change the address structure was truncated on copy, and
the length shortened which I think is incorrect.

AFAICS the only time it could conceivably happen is when a UNIX socket
path is too long, and even then curl should've accounted for that by
having a structure that is large enough to store it. This is why I added
a DEBUGASSERT for debug builds, because I don't think it should ever
happen.

Closes https://github.com/curl/curl/pull/15784

lib/cf-socket.c
lib/cf-socket.h
lib/vquic/curl_msh3.c

index 497a3b965f1250f5b23641d35ea92dc285b42a14..71d6f3f59bee5f118d6be6f47c1ec1d178eb3294 100644 (file)
@@ -306,9 +306,9 @@ tcpkeepalive(struct Curl_easy *data,
  * Assign the address `ai` to the Curl_sockaddr_ex `dest` and
  * set the transport used.
  */
-void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
-                           const struct Curl_addrinfo *ai,
-                           int transport)
+CURLcode Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
+                               const struct Curl_addrinfo *ai,
+                               int transport)
 {
   /*
    * The Curl_sockaddr_ex structure is basically libcurl's external API
@@ -334,9 +334,13 @@ void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
   }
   dest->addrlen = (unsigned int)ai->ai_addrlen;
 
-  if(dest->addrlen > sizeof(struct Curl_sockaddr_storage))
-    dest->addrlen = sizeof(struct Curl_sockaddr_storage);
+  if(dest->addrlen > sizeof(struct Curl_sockaddr_storage)) {
+    DEBUGASSERT(0);
+    return CURLE_TOO_LARGE;
+  }
+
   memcpy(&dest->curl_sa_addr, ai->ai_addr, dest->addrlen);
+  return CURLE_OK;
 }
 
 static CURLcode socket_open(struct Curl_easy *data,
@@ -395,12 +399,16 @@ CURLcode Curl_socket_open(struct Curl_easy *data,
                             curl_socket_t *sockfd)
 {
   struct Curl_sockaddr_ex dummy;
+  CURLcode result;
 
   if(!addr)
     /* if the caller does not want info back, use a local temp copy */
     addr = &dummy;
 
-  Curl_sock_assign_addr(addr, ai, transport);
+  result = Curl_sock_assign_addr(addr, ai, transport);
+  if(result)
+    return result;
+
   return socket_open(data, addr, sockfd);
 }
 
@@ -959,14 +967,20 @@ struct cf_socket_ctx {
   BIT(active);
 };
 
-static void cf_socket_ctx_init(struct cf_socket_ctx *ctx,
-                               const struct Curl_addrinfo *ai,
-                               int transport)
+static CURLcode cf_socket_ctx_init(struct cf_socket_ctx *ctx,
+                                   const struct Curl_addrinfo *ai,
+                                   int transport)
 {
+  CURLcode result;
+
   memset(ctx, 0, sizeof(*ctx));
   ctx->sock = CURL_SOCKET_BAD;
   ctx->transport = transport;
-  Curl_sock_assign_addr(&ctx->addr, ai, transport);
+
+  result = Curl_sock_assign_addr(&ctx->addr, ai, transport);
+  if(result)
+    return result;
+
 #ifdef DEBUGBUILD
   {
     char *p = getenv("CURL_DBG_SOCK_WBLOCK");
@@ -995,6 +1009,8 @@ static void cf_socket_ctx_init(struct cf_socket_ctx *ctx,
     }
   }
 #endif
+
+  return result;
 }
 
 static void cf_socket_close(struct Curl_cfilter *cf, struct Curl_easy *data)
@@ -1805,7 +1821,10 @@ CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
     result = CURLE_OUT_OF_MEMORY;
     goto out;
   }
-  cf_socket_ctx_init(ctx, ai, transport);
+
+  result = cf_socket_ctx_init(ctx, ai, transport);
+  if(result)
+    goto out;
 
   result = Curl_cf_create(&cf, &Curl_cft_tcp, ctx);
 
@@ -1954,7 +1973,10 @@ CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf,
     result = CURLE_OUT_OF_MEMORY;
     goto out;
   }
-  cf_socket_ctx_init(ctx, ai, transport);
+
+  result = cf_socket_ctx_init(ctx, ai, transport);
+  if(result)
+    goto out;
 
   result = Curl_cf_create(&cf, &Curl_cft_udp, ctx);
 
@@ -2006,7 +2028,10 @@ CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf,
     result = CURLE_OUT_OF_MEMORY;
     goto out;
   }
-  cf_socket_ctx_init(ctx, ai, transport);
+
+  result = cf_socket_ctx_init(ctx, ai, transport);
+  if(result)
+    goto out;
 
   result = Curl_cf_create(&cf, &Curl_cft_unix, ctx);
 
index 651034901cd9235a319f7819cb899dacf872a910..1ce8404c07d010a07a544c2d71ce023920324772 100644 (file)
@@ -95,9 +95,9 @@ void Curl_sndbuf_init(curl_socket_t sockfd);
  * Assign the address `ai` to the Curl_sockaddr_ex `dest` and
  * set the transport used.
  */
-void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
-                           const struct Curl_addrinfo *ai,
-                           int transport);
+CURLcode Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
+                               const struct Curl_addrinfo *ai,
+                               int transport);
 
 /**
  * Creates a cfilter that opens a TCP socket to the given address
index fe812f87d2a4bdd57398f335aa92ded702fe2d19..dc43766a81954f5cb621a71e8cb9fe26127cb191 100644 (file)
@@ -132,15 +132,23 @@ struct cf_msh3_ctx {
 
 static void h3_stream_hash_free(void *stream);
 
-static void cf_msh3_ctx_init(struct cf_msh3_ctx *ctx,
-                             const struct Curl_addrinfo *ai)
+static CURLcode cf_msh3_ctx_init(struct cf_msh3_ctx *ctx,
+                                 const struct Curl_addrinfo *ai)
 {
+  CURLcode result;
+
   DEBUGASSERT(!ctx->initialized);
   Curl_hash_offt_init(&ctx->streams, 63, h3_stream_hash_free);
-  Curl_sock_assign_addr(&ctx->addr, ai, TRNSPRT_QUIC);
+
+  result = Curl_sock_assign_addr(&ctx->addr, ai, TRNSPRT_QUIC);
+  if(result)
+    return result;
+
   ctx->sock[SP_LOCAL] = CURL_SOCKET_BAD;
   ctx->sock[SP_REMOTE] = CURL_SOCKET_BAD;
   ctx->initialized = TRUE;
+
+  return result;
 }
 
 static void cf_msh3_ctx_free(struct cf_msh3_ctx *ctx)
@@ -1087,7 +1095,10 @@ CURLcode Curl_cf_msh3_create(struct Curl_cfilter **pcf,
     result = CURLE_OUT_OF_MEMORY;
     goto out;
   }
-  cf_msh3_ctx_init(ctx, ai);
+
+  result = cf_msh3_ctx_init(ctx, ai);
+  if(result)
+    goto out;
 
   result = Curl_cf_create(&cf, &Curl_cft_http3, ctx);