doh: stricter HTTPS RNAME parsing

If any sublabel is longer than 63 octets, abort. This then also catches
compression attempts.

Verified in test 1658

Reported-by: netspacer.research
Closes #22124
This commit is contained in:
Daniel Stenberg 2026-06-22 09:10:15 +02:00
parent e8e3af2abb
commit ab779d4e4a
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
3 changed files with 31 additions and 3 deletions

View file

@ -1092,10 +1092,14 @@ static CURLcode doh_decode_rdata_name(const unsigned char **buf,
DEBUGASSERT(buf && remaining && dnsname);
if(!buf || !remaining || !dnsname || !*remaining)
return CURLE_OUT_OF_MEMORY;
curlx_dyn_init(&thename, CURL_MAXLEN_host_name);
curlx_dyn_init(&thename, CURL_MAXLEN_HOST_NAME);
rem = *remaining;
cp = *buf;
clen = *cp++;
/* RFC 9460 says it must be uncompressed */
if(clen > 63)
return CURLE_WEIRD_SERVER_REPLY;
if(clen == 0) {
/* special case - return "." as name */
if(curlx_dyn_addn(&thename, ".", 1))
@ -1117,6 +1121,11 @@ static CURLcode doh_decode_rdata_name(const unsigned char **buf,
return CURLE_OUT_OF_MEMORY;
}
clen = *cp++;
if(clen > 63) {
/* invalid format */
curlx_dyn_free(&thename);
return CURLE_WEIRD_SERVER_REPLY;
}
}
*buf = cp;
*remaining = rem - 1;

View file

@ -31,7 +31,7 @@
#ifdef USE_HTTPSRR
#define CURL_MAXLEN_host_name 253
#define CURL_MAXLEN_HOST_NAME 253
#define MAX_HTTPSRR_ALPNS 4
struct Curl_easy;

View file

@ -493,7 +493,26 @@ static CURLcode test_unit1658(const char *arg)
"ech:fe80dabbc1ff7eb38a22123456789123|"
"ipv6:fe80:dabb:c1ff:fea3:8a22:1234:5678:9123|"
"ipv6:ee80:dabb:c1ff:fea3:8a22:1234:5678:9125|"
}
},
{
"rname too long label",
(const unsigned char *)"\x00\x00" /* 16-bit prio */
"\x40"
"0123456789012345678901234567890123456789012345678901234567890123"
"\x04some\x00", /* RNAME */
73,
"r:27|",
},
{
"rname long label",
(const unsigned char *)"\x00\x00" /* 16-bit prio */
"\x3f"
"012345678901234567890123456789012345678901234567890123456789012"
"\x04some\x00", /* RNAME */
72,
"r:0|p:0|"
"012345678901234567890123456789012345678901234567890123456789012.some.|",
},
};
CURLcode result = CURLE_OUT_OF_MEMORY;