ssls: fix potential memory leak on import

Memory can be leaked when importing corrupted SSL session data that
carry the same data fields repeatedly.

Fixes #22323

Closes #22324
This commit is contained in:
Stefan Eissing 2026-07-14 09:35:58 +02:00 committed by Viktor Szakats
parent 94fab2d210
commit 0dc22b690d
No known key found for this signature in database
9 changed files with 201 additions and 9 deletions

View file

@ -380,9 +380,9 @@ static void cf_ssl_scache_session_ldestroy(void *udata, void *obj)
{
struct Curl_ssl_session *s = obj;
(void)udata;
curlx_free(CURL_UNCONST(s->sdata));
curlx_free(CURL_UNCONST(s->quic_tp));
curlx_free((void *)s->alpn);
curlx_free(s->sdata);
curlx_free(s->quic_tp);
curlx_free(s->alpn);
curlx_free(s);
}

View file

@ -122,13 +122,13 @@ CURLcode Curl_ssl_scache_add_obj(struct Curl_cfilter *cf,
/* All about an SSL session ticket */
struct Curl_ssl_session {
const void *sdata; /* session ticket data, plain bytes */
uint8_t *sdata; /* session ticket data, plain bytes */
size_t sdata_len; /* number of bytes in sdata */
curl_off_t valid_until; /* seconds since EPOCH until ticket expires */
int ietf_tls_id; /* TLS protocol identifier negotiated */
char *alpn; /* APLN TLS negotiated protocol string */
size_t earlydata_max; /* max 0-RTT data supported by peer */
const unsigned char *quic_tp; /* Optional QUIC transport param bytes */
uint8_t *quic_tp; /* Optional QUIC transport param bytes */
size_t quic_tp_len; /* number of bytes in quic_tp */
struct Curl_llist_node list; /* internal storage handling */
BIT(sectrust_verified); /* session comes from sectrust verified TLS */

View file

@ -244,6 +244,7 @@ CURLcode Curl_ssl_session_unpack(struct Curl_easy *data,
uint16_t val16;
uint32_t val32;
uint64_t val64;
size_t dlen;
CURLcode result;
DEBUGASSERT(buf);
@ -271,6 +272,7 @@ CURLcode Curl_ssl_session_unpack(struct Curl_easy *data,
switch(val8) {
case CURL_SPACK_ALPN:
curlx_free(s->alpn);
result = spack_decstr16(&s->alpn, &buf, end);
if(result)
goto out;
@ -288,17 +290,21 @@ CURLcode Curl_ssl_session_unpack(struct Curl_easy *data,
s->ietf_tls_id = val16;
break;
case CURL_SPACK_QUICTP: {
result = spack_decdata16(&pval8, &s->quic_tp_len, &buf, end);
result = spack_decdata16(&pval8, &dlen, &buf, end);
if(result)
goto out;
curlx_free(s->quic_tp);
s->quic_tp = pval8;
s->quic_tp_len = dlen;
break;
}
case CURL_SPACK_TICKET: {
result = spack_decdata16(&pval8, &s->sdata_len, &buf, end);
result = spack_decdata16(&pval8, &dlen, &buf, end);
if(result)
goto out;
curlx_free(s->sdata);
s->sdata = pval8;
s->sdata_len = dlen;
break;
}
case CURL_SPACK_VALID_UNTIL: