From d1dc6d5b81b7871ae4d0f23c4c3f5ddb5a87f458 Mon Sep 17 00:00:00 2001 From: Alex J Date: Tue, 6 Oct 2026 18:16:29 +0300 Subject: [PATCH] dnssec: do not read the window length byte past the end of an NSEC bitmap ldns_nsec_bitmap_covers_type(), ldns_nsec_bitmap_set_type() and ldns_nsec_bitmap_clear_type() walk an NSEC/NSEC3 type bitmap as a sequence of windows, each introduced by a two-byte header (window number, bitmap length). The loop condition only guaranteed that one byte remained (dptr < dend), while both the body and the advance step read dptr[1], the length byte. A bitmap whose data ends immediately after a window number therefore caused a one-byte read past the end of the buffer. Require two bytes before entering the loop, so a trailing partial window header is treated as the end of the bitmap. A well-formed bitmap always has both header bytes present, so behaviour on valid input is unchanged, including for a type in the last window. --- dnssec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnssec.c b/dnssec.c index 5b5d5699..f036d166 100644 --- a/dnssec.c +++ b/dnssec.c @@ -1420,7 +1420,7 @@ ldns_nsec_bitmap_covers_type(const ldns_rdf* bitmap, ldns_rr_type type) /* Type Bitmap = ( Window Block # | Bitmap Length | Bitmap ) + * dptr[0] dptr[1] dptr[2:] */ - while (dptr < dend && dptr[0] <= window) { + while (dptr + 1 < dend && dptr[0] <= window) { if (dptr[0] == window && subtype / 8 < dptr[1] && dptr + dptr[1] + 2 <= dend) { @@ -1457,7 +1457,7 @@ ldns_nsec_bitmap_set_type(ldns_rdf* bitmap, ldns_rr_type type) /* Type Bitmap = ( Window Block # | Bitmap Length | Bitmap ) + * dptr[0] dptr[1] dptr[2:] */ - while (dptr < dend && dptr[0] <= window) { + while (dptr + 1 < dend && dptr[0] <= window) { if (dptr[0] == window && subtype / 8 < dptr[1] && dptr + dptr[1] + 2 <= dend) { @@ -1496,7 +1496,7 @@ ldns_nsec_bitmap_clear_type(ldns_rdf* bitmap, ldns_rr_type type) /* Type Bitmap = ( Window Block # | Bitmap Length | Bitmap ) + * dptr[0] dptr[1] dptr[2:] */ - while (dptr < dend && dptr[0] <= window) { + while (dptr + 1 < dend && dptr[0] <= window) { if (dptr[0] == window && subtype / 8 < dptr[1] && dptr + dptr[1] + 2 <= dend) {