From 1792f2231fb246396e3f50e465194dd93565b1c7 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Tue, 28 Jul 2015 23:09:23 +0200 Subject: resolve: packet - fix append_types() We were counting the number of bits set rather than the number of bytes they occupied. --- src/resolve/resolved-dns-packet.c | 40 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 649e8b74e1..8c5306cc83 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -508,23 +508,21 @@ static int dns_packet_append_type_window(DnsPacket *p, uint8_t window, uint8_t l assert(p); assert(types); + assert(length > 0); saved_size = p->size; - if (length != 0) { - - r = dns_packet_append_uint8(p, window, NULL); - if (r < 0) - goto fail; + r = dns_packet_append_uint8(p, window, NULL); + if (r < 0) + goto fail; - r = dns_packet_append_uint8(p, length, NULL); - if (r < 0) - goto fail; + r = dns_packet_append_uint8(p, length, NULL); + if (r < 0) + goto fail; - r = dns_packet_append_blob(p, types, length, NULL); - if (r < 0) - goto fail; - } + r = dns_packet_append_blob(p, types, length, NULL); + if (r < 0) + goto fail; if (start) *start = saved_size; @@ -538,7 +536,7 @@ fail: static int dns_packet_append_types(DnsPacket *p, Bitmap *types, size_t *start) { Iterator i; uint8_t window = 0; - uint8_t len = 0; + uint8_t entry = 0; uint8_t bitmaps[32] = {}; unsigned n; size_t saved_size; @@ -550,30 +548,24 @@ static int dns_packet_append_types(DnsPacket *p, Bitmap *types, size_t *start) { saved_size = p->size; BITMAP_FOREACH(n, types, i) { - uint8_t entry; - assert(n <= 0xffff); - if ((n << 8) != window) { - r = dns_packet_append_type_window(p, window, len, bitmaps, NULL); + if ((n >> 8) != window && bitmaps[entry / 8] != 0) { + r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL); if (r < 0) goto fail; - if (len > 0) { - len = 0; - zero(bitmaps); - } + zero(bitmaps); } - window = n << 8; - len ++; + window = n >> 8; entry = n & 255; bitmaps[entry / 8] |= 1 << (7 - (entry % 8)); } - r = dns_packet_append_type_window(p, window, len, bitmaps, NULL); + r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL); if (r < 0) goto fail; -- cgit v1.2.3-54-g00ecf From 2ad613addbabc3ffec6d12a1b5c62ff0d07b4a29 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Tue, 28 Jul 2015 23:10:18 +0200 Subject: resolved: packet - fix read_type_window() We were tracking the bit offset inside each byte, rather than inside the whole bitmap. --- src/resolve/resolved-dns-packet.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 8c5306cc83..88a3089a72 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -1156,6 +1156,7 @@ static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *sta uint8_t window; uint8_t length; const uint8_t *bitmap; + uint8_t bit = 0; unsigned i; bool found = false; size_t saved_rindex; @@ -1187,10 +1188,10 @@ static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *sta for (i = 0; i < length; i++) { uint8_t bitmask = 1 << 7; - uint8_t bit = 0; if (!bitmap[i]) { found = false; + bit += 8; continue; } -- cgit v1.2.3-54-g00ecf From bfcc67093d1a8f3f38d3b412fca24b00e775caaa Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Tue, 28 Jul 2015 23:16:52 +0200 Subject: resolved: packet - refuse empty type bitmaps The NSEC type itself must at least be in the bitmap, so NSEC records with empty bitmaps must be bogus. --- src/resolve/resolved-dns-packet.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 88a3089a72..39951a362c 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -1666,8 +1666,12 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { if (r < 0) goto fail; - /* NSEC RRs with empty bitmpas makes no sense, but the RFC does not explicitly forbid them - so we allow it */ + /* The types bitmap must contain at least the NSEC record itself, so an empty bitmap means + something went wrong */ + if (bitmap_isclear(rr->nsec.types)) { + r = -EBADMSG; + goto fail; + } break; -- cgit v1.2.3-54-g00ecf