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)
_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)
if (r < 0)
return r;
- if (p->rindex + rdlength > p->size)
+ if (rdlength > p->size - p->rindex)
return -EBADMSG;
offset = p->rindex;
} else {
DnsTxtItem *last = NULL;
- while (p->rindex < offset + rdlength) {
+ while (p->rindex - offset < rdlength) {
DnsTxtItem *i;
const void *data;
size_t sz;
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,
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
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 */
if (r < 0)
return r;
- if (rdlength + offset < p->rindex)
+ if (rdlength < p->rindex - offset)
return -EBADMSG;
r = dns_packet_read_memdup(p,
}
if (r < 0)
return r;
- if (p->rindex != offset + rdlength)
+ if (p->rindex - offset != rdlength)
return -EBADMSG;
if (ret)