- Fix to check for invalid http content length and chunk size,

and to check the RR rdata field lengths when decompressing and
  inserting RRs from an authority zone transfer. This stops
  large memory use and heap buffer-overflow read errors. Thanks
  to Haruto Kimura (Stella) for the report.
This commit is contained in:
W.C.A. Wijngaards
2026-03-24 08:45:52 +01:00
parent 535d899bef
commit 315077b9e6
3 changed files with 31 additions and 4 deletions
+7
View File
@@ -1,3 +1,10 @@
24 March 2026: Wouter
- Fix to check for invalid http content length and chunk size,
and to check the RR rdata field lengths when decompressing and
inserting RRs from an authority zone transfer. This stops
large memory use and heap buffer-overflow read errors. Thanks
to Haruto Kimura (Stella) for the report.
20 March 2026: Wouter
- Fix for testcode pktview to check buffer size and log errors.
+5
View File
@@ -1384,6 +1384,9 @@ decompress_rr_into_buffer(struct sldns_buffer* buf, uint8_t* pkt,
len = 0;
break;
case LDNS_RDF_TYPE_STR:
/* Check rdlen for resilience, because it is
* checked above, that rdlen > 0 */
if(rdlen < 1) return 0; /* malformed */
len = rd[0] + 1;
break;
default:
@@ -1391,6 +1394,8 @@ decompress_rr_into_buffer(struct sldns_buffer* buf, uint8_t* pkt,
break;
}
if(len) {
if(len > rdlen)
return 0; /* malformed */
if(!sldns_buffer_available(buf, len))
return 0; /* too long for buffer */
sldns_buffer_write(buf, rd, len);
+19 -4
View File
@@ -4870,8 +4870,17 @@ http_process_initial_header(struct comm_point* c)
return 0;
}
} else if(strncasecmp(line, "Content-Length: ", 16) == 0) {
if(!c->http_is_chunked)
c->tcp_byte_count = (size_t)atoi(line+16);
if(!c->http_is_chunked) {
char* end = NULL;
long long cl;
errno = 0;
cl = strtoll(line+16, &end, 10);
if(end == line+16 || errno != 0 || cl < 0) {
verbose(VERB_ALGO, "http invalid Content-Length: " ARG_LL "d", cl);
return 0; /* reject */
}
c->tcp_byte_count = (size_t)cl;
}
} else if(strncasecmp(line, "Transfer-Encoding: chunked", 19+7) == 0) {
c->tcp_byte_count = 0;
c->http_is_chunked = 1;
@@ -4927,9 +4936,15 @@ http_process_chunk_header(struct comm_point* c)
if(c->http_in_chunk_headers == 1) {
/* read chunked start line */
char* end = NULL;
c->tcp_byte_count = (size_t)strtol(line, &end, 16);
if(end == line)
long chunk_sz;
errno = 0;
chunk_sz = strtol(line, &end, 16);
if(end == line || errno != 0 || chunk_sz < 0) {
verbose(VERB_ALGO, "http invalid chunk size: %ld",
chunk_sz);
return 0;
}
c->tcp_byte_count = (size_t)chunk_sz;
c->http_in_chunk_headers = 0;
/* remove header text from front of buffer */
http_moveover_buffer(c->buffer);