1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-21 18:03:41 +03:00

resolve: fix possible integer overflow

(cherry picked from commit 370999c05bd21b18056686dfb27f999acda7c0b6)
(cherry picked from commit b7fc4ffe9747b7a967b43cbff5a96286976946ee)
This commit is contained in:
Yu Watanabe 2022-07-08 22:13:24 +09:00 committed by Zbigniew Jędrzejewski-Szmek
parent 63c0ce2346
commit 79d9afd3d6

View File

@ -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) { int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
assert(p); assert(p);
assert(p->rindex <= p->size);
if (p->rindex + sz > p->size) if (sz > p->size - p->rindex)
return -EMSGSIZE; return -EMSGSIZE;
if (ret) 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); _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = REWINDER_INIT(p);
int r; 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); r = dns_packet_read_type_window(p, types, NULL);
if (r < 0) if (r < 0)
return r; return r;
assert(p->rindex >= rewinder.saved_rindex);
/* don't read past end of current RR */ /* don't read past end of current RR */
if (p->rindex > rewinder.saved_rindex + size) if (p->rindex - rewinder.saved_rindex > size)
return -EBADMSG; return -EBADMSG;
} }
if (p->rindex != rewinder.saved_rindex + size) if (p->rindex - rewinder.saved_rindex != size)
return -EBADMSG; return -EBADMSG;
if (start) if (start)
@ -1716,7 +1719,7 @@ int dns_packet_read_rr(
if (r < 0) if (r < 0)
return r; return r;
if (p->rindex + rdlength > p->size) if (rdlength > p->size - p->rindex)
return -EBADMSG; return -EBADMSG;
offset = p->rindex; offset = p->rindex;
@ -1760,7 +1763,7 @@ int dns_packet_read_rr(
} else { } else {
DnsTxtItem *last = NULL; DnsTxtItem *last = NULL;
while (p->rindex < offset + rdlength) { while (p->rindex - offset < rdlength) {
DnsTxtItem *i; DnsTxtItem *i;
const void *data; const void *data;
size_t sz; size_t sz;
@ -1992,7 +1995,7 @@ int dns_packet_read_rr(
if (r < 0) if (r < 0)
return r; return r;
if (rdlength + offset < p->rindex) if (rdlength < p->rindex - offset)
return -EBADMSG; return -EBADMSG;
r = dns_packet_read_memdup(p, offset + rdlength - p->rindex, r = dns_packet_read_memdup(p, offset + rdlength - p->rindex,
@ -2019,6 +2022,9 @@ int dns_packet_read_rr(
if (r < 0) if (r < 0)
return r; return r;
if (rdlength < p->rindex - offset)
return -EBADMSG;
r = dns_packet_read_type_windows(p, &rr->nsec.types, offset + rdlength - p->rindex, NULL); 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 /* 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) if (r < 0)
return r; return r;
if (rdlength < p->rindex - offset)
return -EBADMSG;
r = dns_packet_read_type_windows(p, &rr->nsec3.types, offset + rdlength - p->rindex, NULL); 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 */ /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
@ -2107,7 +2116,7 @@ int dns_packet_read_rr(
if (r < 0) if (r < 0)
return r; return r;
if (rdlength + offset < p->rindex) if (rdlength < p->rindex - offset)
return -EBADMSG; return -EBADMSG;
r = dns_packet_read_memdup(p, r = dns_packet_read_memdup(p,
@ -2126,7 +2135,7 @@ int dns_packet_read_rr(
} }
if (r < 0) if (r < 0)
return r; return r;
if (p->rindex != offset + rdlength) if (p->rindex - offset != rdlength)
return -EBADMSG; return -EBADMSG;
if (ret) if (ret)