diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index ff1ef4454d..3ff5ac341c 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -1254,8 +1254,9 @@ int dns_packet_append_answer(DnsPacket *p, DnsAnswer *a, unsigned *completed) { int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) { assert(p); + assert(p->rindex <= p->size); - if (p->rindex + sz > p->size) + if (sz > p->size - p->rindex) return -EMSGSIZE; if (ret) @@ -1595,17 +1596,19 @@ static int dns_packet_read_type_windows(DnsPacket *p, Bitmap **types, size_t siz _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = REWINDER_INIT(p); int r; - while (p->rindex < rewinder.saved_rindex + size) { + while (p->rindex - rewinder.saved_rindex < size) { r = dns_packet_read_type_window(p, types, NULL); if (r < 0) return r; + assert(p->rindex >= rewinder.saved_rindex); + /* don't read past end of current RR */ - if (p->rindex > rewinder.saved_rindex + size) + if (p->rindex - rewinder.saved_rindex > size) return -EBADMSG; } - if (p->rindex != rewinder.saved_rindex + size) + if (p->rindex - rewinder.saved_rindex != size) return -EBADMSG; if (start) @@ -1716,7 +1719,7 @@ int dns_packet_read_rr( if (r < 0) return r; - if (p->rindex + rdlength > p->size) + if (rdlength > p->size - p->rindex) return -EBADMSG; offset = p->rindex; @@ -1760,7 +1763,7 @@ int dns_packet_read_rr( } else { DnsTxtItem *last = NULL; - while (p->rindex < offset + rdlength) { + while (p->rindex - offset < rdlength) { DnsTxtItem *i; const void *data; size_t sz; @@ -1992,7 +1995,7 @@ int dns_packet_read_rr( if (r < 0) return r; - if (rdlength + offset < p->rindex) + if (rdlength < p->rindex - offset) return -EBADMSG; r = dns_packet_read_memdup(p, offset + rdlength - p->rindex, @@ -2019,6 +2022,9 @@ int dns_packet_read_rr( if (r < 0) return r; + if (rdlength < p->rindex - offset) + return -EBADMSG; + r = dns_packet_read_type_windows(p, &rr->nsec.types, offset + rdlength - p->rindex, NULL); /* We accept empty NSEC bitmaps. The bit indicating the presence of the NSEC record itself @@ -2064,6 +2070,9 @@ int dns_packet_read_rr( if (r < 0) return r; + if (rdlength < p->rindex - offset) + return -EBADMSG; + r = dns_packet_read_type_windows(p, &rr->nsec3.types, offset + rdlength - p->rindex, NULL); /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */ @@ -2107,7 +2116,7 @@ int dns_packet_read_rr( if (r < 0) return r; - if (rdlength + offset < p->rindex) + if (rdlength < p->rindex - offset) return -EBADMSG; r = dns_packet_read_memdup(p, @@ -2126,7 +2135,7 @@ int dns_packet_read_rr( } if (r < 0) return r; - if (p->rindex != offset + rdlength) + if (p->rindex - offset != rdlength) return -EBADMSG; if (ret)