diff options
author | 2012-06-06 16:54:33 +0000 | |
---|---|---|
committer | 2012-06-06 16:54:33 +0000 | |
commit | 4ca673f3df5d9679d1d3bdb337a97b8ceec3e666 (patch) | |
tree | b31c92a5388dda7d523c316c135477ca2dc5af5c | |
parent | tweak previous; (diff) | |
download | wireguard-openbsd-4ca673f3df5d9679d1d3bdb337a97b8ceec3e666.tar.xz wireguard-openbsd-4ca673f3df5d9679d1d3bdb337a97b8ceec3e666.zip |
Add a fix for CVE-2012-1667, backported from ISC BIND. ok millert@
http://www.isc.org/software/bind/advisories/cve-2012-1667
Distinguish rdata removed by BIND due to duplication, from zero-length rdata
received from a server. Otherwise a server supplying zero-length rdata sections
can trigger crashes or possible memory disclosure to the client.
Primarily affects recursive servers.
-rw-r--r-- | usr.sbin/bind/lib/dns/rdata.c | 4 | ||||
-rw-r--r-- | usr.sbin/bind/lib/dns/rdataslab.c | 11 |
2 files changed, 10 insertions, 5 deletions
diff --git a/usr.sbin/bind/lib/dns/rdata.c b/usr.sbin/bind/lib/dns/rdata.c index c3b135dd149..57a1eb414f0 100644 --- a/usr.sbin/bind/lib/dns/rdata.c +++ b/usr.sbin/bind/lib/dns/rdata.c @@ -334,8 +334,8 @@ dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) { REQUIRE(rdata1 != NULL); REQUIRE(rdata2 != NULL); - REQUIRE(rdata1->data != NULL); - REQUIRE(rdata2->data != NULL); + REQUIRE(rdata1->length == 0 || rdata1->data != NULL); + REQUIRE(rdata2->length == 0 || rdata2->data != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2)); diff --git a/usr.sbin/bind/lib/dns/rdataslab.c b/usr.sbin/bind/lib/dns/rdataslab.c index 6635e081bc4..21541d1d739 100644 --- a/usr.sbin/bind/lib/dns/rdataslab.c +++ b/usr.sbin/bind/lib/dns/rdataslab.c @@ -128,6 +128,11 @@ isc_result_t dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, isc_region_t *region, unsigned int reservelen) { + /* + * Use &removed as a sentinel pointer for duplicate + * rdata as rdata.data == NULL is valid. + */ + static unsigned char removed; struct xrdata *x; unsigned char *rawbuf; #if DNS_RDATASET_FIXED @@ -166,6 +171,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, INSIST(result == ISC_R_SUCCESS); dns_rdata_init(&x[i].rdata); dns_rdataset_current(rdataset, &x[i].rdata); + INSIST(x[i].rdata.data != &removed); #if DNS_RDATASET_FIXED x[i].order = i; #endif @@ -198,8 +204,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, */ for (i = 1; i < nalloc; i++) { if (compare_rdata(&x[i-1].rdata, &x[i].rdata) == 0) { - x[i-1].rdata.data = NULL; - x[i-1].rdata.length = 0; + x[i-1].rdata.data = &removed; #if DNS_RDATASET_FIXED /* * Preserve the least order so A, B, A -> A, B @@ -275,7 +280,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, #endif for (i = 0; i < nalloc; i++) { - if (x[i].rdata.data == NULL) + if (x[i].rdata.data == &removed) continue; #if DNS_RDATASET_FIXED offsettable[x[i].order] = rawbuf - offsetbase; |