]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolve: fix possible integer overflow 23954/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 8 Jul 2022 13:13:24 +0000 (22:13 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 8 Jul 2022 13:13:24 +0000 (22:13 +0900)
src/resolve/resolved-dns-packet.c

index 0e32fb96298a7e729910082311c96f4cd4c73e89..97809439a58d2c4e7fd3b799780df9761b2989c6 100644 (file)
@@ -1251,8 +1251,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)
@@ -1592,17 +1593,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)
@@ -1713,7 +1716,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;
@@ -1757,7 +1760,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;
@@ -1989,7 +1992,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,
@@ -2016,6 +2019,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
@@ -2061,6 +2067,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 */
@@ -2104,7 +2113,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,
@@ -2123,7 +2132,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)