From: Jay Satiro Date: Thu, 19 Dec 2024 22:12:02 +0000 (-0500) Subject: cf-socket: error if address can't be copied X-Git-Tag: curl-8_12_0~290 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=55367416f5636d0535fb76a4791667587a16c197;p=thirdparty%2Fcurl.git cf-socket: error if address can't be copied - 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 --- diff --git a/lib/cf-socket.c b/lib/cf-socket.c index 497a3b965f..71d6f3f59b 100644 --- a/lib/cf-socket.c +++ b/lib/cf-socket.c @@ -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); diff --git a/lib/cf-socket.h b/lib/cf-socket.h index 651034901c..1ce8404c07 100644 --- a/lib/cf-socket.h +++ b/lib/cf-socket.h @@ -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 diff --git a/lib/vquic/curl_msh3.c b/lib/vquic/curl_msh3.c index fe812f87d2..dc43766a81 100644 --- a/lib/vquic/curl_msh3.c +++ b/lib/vquic/curl_msh3.c @@ -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);