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
This commit is contained in:
parent
b7be4011c6
commit
55367416f5
@ -306,7 +306,7 @@ tcpkeepalive(struct Curl_easy *data,
|
|||||||
* Assign the address `ai` to the Curl_sockaddr_ex `dest` and
|
* Assign the address `ai` to the Curl_sockaddr_ex `dest` and
|
||||||
* set the transport used.
|
* set the transport used.
|
||||||
*/
|
*/
|
||||||
void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
|
CURLcode Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
|
||||||
const struct Curl_addrinfo *ai,
|
const struct Curl_addrinfo *ai,
|
||||||
int transport)
|
int transport)
|
||||||
{
|
{
|
||||||
@ -334,9 +334,13 @@ void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
|
|||||||
}
|
}
|
||||||
dest->addrlen = (unsigned int)ai->ai_addrlen;
|
dest->addrlen = (unsigned int)ai->ai_addrlen;
|
||||||
|
|
||||||
if(dest->addrlen > sizeof(struct Curl_sockaddr_storage))
|
if(dest->addrlen > sizeof(struct Curl_sockaddr_storage)) {
|
||||||
dest->addrlen = sizeof(struct Curl_sockaddr_storage);
|
DEBUGASSERT(0);
|
||||||
|
return CURLE_TOO_LARGE;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&dest->curl_sa_addr, ai->ai_addr, dest->addrlen);
|
memcpy(&dest->curl_sa_addr, ai->ai_addr, dest->addrlen);
|
||||||
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode socket_open(struct Curl_easy *data,
|
static CURLcode socket_open(struct Curl_easy *data,
|
||||||
@ -395,12 +399,16 @@ CURLcode Curl_socket_open(struct Curl_easy *data,
|
|||||||
curl_socket_t *sockfd)
|
curl_socket_t *sockfd)
|
||||||
{
|
{
|
||||||
struct Curl_sockaddr_ex dummy;
|
struct Curl_sockaddr_ex dummy;
|
||||||
|
CURLcode result;
|
||||||
|
|
||||||
if(!addr)
|
if(!addr)
|
||||||
/* if the caller does not want info back, use a local temp copy */
|
/* if the caller does not want info back, use a local temp copy */
|
||||||
addr = &dummy;
|
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);
|
return socket_open(data, addr, sockfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -959,14 +967,20 @@ struct cf_socket_ctx {
|
|||||||
BIT(active);
|
BIT(active);
|
||||||
};
|
};
|
||||||
|
|
||||||
static void cf_socket_ctx_init(struct cf_socket_ctx *ctx,
|
static CURLcode cf_socket_ctx_init(struct cf_socket_ctx *ctx,
|
||||||
const struct Curl_addrinfo *ai,
|
const struct Curl_addrinfo *ai,
|
||||||
int transport)
|
int transport)
|
||||||
{
|
{
|
||||||
|
CURLcode result;
|
||||||
|
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
ctx->sock = CURL_SOCKET_BAD;
|
ctx->sock = CURL_SOCKET_BAD;
|
||||||
ctx->transport = transport;
|
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
|
#ifdef DEBUGBUILD
|
||||||
{
|
{
|
||||||
char *p = getenv("CURL_DBG_SOCK_WBLOCK");
|
char *p = getenv("CURL_DBG_SOCK_WBLOCK");
|
||||||
@ -995,6 +1009,8 @@ static void cf_socket_ctx_init(struct cf_socket_ctx *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cf_socket_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
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;
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
goto out;
|
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);
|
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;
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
goto out;
|
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);
|
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;
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
goto out;
|
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);
|
result = Curl_cf_create(&cf, &Curl_cft_unix, ctx);
|
||||||
|
|
||||||
|
|||||||
@ -95,7 +95,7 @@ void Curl_sndbuf_init(curl_socket_t sockfd);
|
|||||||
* Assign the address `ai` to the Curl_sockaddr_ex `dest` and
|
* Assign the address `ai` to the Curl_sockaddr_ex `dest` and
|
||||||
* set the transport used.
|
* set the transport used.
|
||||||
*/
|
*/
|
||||||
void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
|
CURLcode Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
|
||||||
const struct Curl_addrinfo *ai,
|
const struct Curl_addrinfo *ai,
|
||||||
int transport);
|
int transport);
|
||||||
|
|
||||||
|
|||||||
@ -132,15 +132,23 @@ struct cf_msh3_ctx {
|
|||||||
|
|
||||||
static void h3_stream_hash_free(void *stream);
|
static void h3_stream_hash_free(void *stream);
|
||||||
|
|
||||||
static void cf_msh3_ctx_init(struct cf_msh3_ctx *ctx,
|
static CURLcode cf_msh3_ctx_init(struct cf_msh3_ctx *ctx,
|
||||||
const struct Curl_addrinfo *ai)
|
const struct Curl_addrinfo *ai)
|
||||||
{
|
{
|
||||||
|
CURLcode result;
|
||||||
|
|
||||||
DEBUGASSERT(!ctx->initialized);
|
DEBUGASSERT(!ctx->initialized);
|
||||||
Curl_hash_offt_init(&ctx->streams, 63, h3_stream_hash_free);
|
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_LOCAL] = CURL_SOCKET_BAD;
|
||||||
ctx->sock[SP_REMOTE] = CURL_SOCKET_BAD;
|
ctx->sock[SP_REMOTE] = CURL_SOCKET_BAD;
|
||||||
ctx->initialized = TRUE;
|
ctx->initialized = TRUE;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cf_msh3_ctx_free(struct cf_msh3_ctx *ctx)
|
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;
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
goto out;
|
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);
|
result = Curl_cf_create(&cf, &Curl_cft_http3, ctx);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user