From 4601d4299a2bce82f44d997cd1c1e99bd04c9adc Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Thu, 6 Feb 2025 15:50:52 -0800 Subject: [PATCH] fix and simplify dns_rdataset_equal() and _equalx() if both rdataslabs being compared have zero length, return true. also, since these functions are only ever called on slabheaders with sizeof(dns_slabheader_t) as the reserve length, we can simplify the API: remove the reservelen argument, and pass the slabs as type dns_slabheader_t * instead of unsigned char *. --- lib/dns/include/dns/rdataslab.h | 8 +++----- lib/dns/qpcache.c | 8 ++------ lib/dns/rdataslab.c | 20 +++++++++++--------- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/lib/dns/include/dns/rdataslab.h b/lib/dns/include/dns/rdataslab.h index c81fe9777f..15437f0d4a 100644 --- a/lib/dns/include/dns/rdataslab.h +++ b/lib/dns/include/dns/rdataslab.h @@ -251,8 +251,7 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, */ bool -dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2, - unsigned int reservelen); +dns_rdataslab_equal(dns_slabheader_t *slab1, dns_slabheader_t *slab2); /*%< * Compare two rdataslabs for equality. This does _not_ do a full * DNSSEC comparison. @@ -264,9 +263,8 @@ dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2, *\li true if the slabs are equal, false otherwise. */ bool -dns_rdataslab_equalx(unsigned char *slab1, unsigned char *slab2, - unsigned int reservelen, dns_rdataclass_t rdclass, - dns_rdatatype_t type); +dns_rdataslab_equalx(dns_slabheader_t *slab1, dns_slabheader_t *slab2, + dns_rdataclass_t rdclass, dns_rdatatype_t type); /*%< * Compare two rdataslabs for DNSSEC equality. * diff --git a/lib/dns/qpcache.c b/lib/dns/qpcache.c index c5ea5a1e31..f63be9ec44 100644 --- a/lib/dns/qpcache.c +++ b/lib/dns/qpcache.c @@ -2884,9 +2884,7 @@ find_header: if (ACTIVE(header, now) && header->type == dns_rdatatype_ns && EXISTS(header) && EXISTS(newheader) && header->trust >= newheader->trust && - dns_rdataslab_equalx((unsigned char *)header, - (unsigned char *)newheader, - (unsigned int)(sizeof(*newheader)), + dns_rdataslab_equalx(header, newheader, qpdb->common.rdclass, (dns_rdatatype_t)header->type)) { @@ -2950,9 +2948,7 @@ find_header: header->type == DNS_SIGTYPE(dns_rdatatype_ds)) && EXISTS(header) && EXISTS(newheader) && header->trust >= newheader->trust && - dns_rdataslab_equal((unsigned char *)header, - (unsigned char *)newheader, - (unsigned int)(sizeof(*newheader)))) + dns_rdataslab_equal(header, newheader)) { /* * Honour the new ttl if it is less than the diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c index ce0dfeb3f4..27f85fc2f4 100644 --- a/lib/dns/rdataslab.c +++ b/lib/dns/rdataslab.c @@ -714,20 +714,21 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, } bool -dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2, - unsigned int reservelen) { +dns_rdataslab_equal(dns_slabheader_t *slab1, dns_slabheader_t *slab2) { unsigned char *current1 = NULL, *current2 = NULL; unsigned int count1, count2; unsigned int length1, length2; - current1 = slab1 + reservelen; + current1 = (unsigned char *)slab1 + sizeof(dns_slabheader_t); count1 = get_uint16(current1); - current2 = slab2 + reservelen; + current2 = (unsigned char *)slab2 + sizeof(dns_slabheader_t); count2 = get_uint16(current2); if (count1 != count2) { return false; + } else if (count1 == 0) { + return true; } while (count1-- > 0) { @@ -747,22 +748,23 @@ dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2, } bool -dns_rdataslab_equalx(unsigned char *slab1, unsigned char *slab2, - unsigned int reservelen, dns_rdataclass_t rdclass, - dns_rdatatype_t type) { +dns_rdataslab_equalx(dns_slabheader_t *slab1, dns_slabheader_t *slab2, + dns_rdataclass_t rdclass, dns_rdatatype_t type) { unsigned char *current1 = NULL, *current2 = NULL; unsigned int count1, count2; dns_rdata_t rdata1 = DNS_RDATA_INIT; dns_rdata_t rdata2 = DNS_RDATA_INIT; - current1 = slab1 + reservelen; + current1 = (unsigned char *)slab1 + sizeof(dns_slabheader_t); count1 = get_uint16(current1); - current2 = slab2 + reservelen; + current2 = (unsigned char *)slab2 + sizeof(dns_slabheader_t); count2 = get_uint16(current2); if (count1 != count2) { return false; + } else if (count1 == 0) { + return true; } while (count1-- > 0) {