[9.20] fix: usr: Fix zone verification of NSEC3 signed zones

Previously, when computing the compressed bitmap during verification of an NSEC3-signed zone, an undersized buffer was used that resulted in an out-of-bounds write if there were too many active windows in the bitmap. This impacted mirror zones which are NSEC3-signed, `dnssec-signzone` and `dnssec-verifyzone`. This has been fixed.

Closes #5834

Backport of MR !11804

Merge branch 'backport-5834-fix-cbm-size-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11833
This commit is contained in:
Mark Andrews 2026-04-10 18:08:15 +10:00
commit de4a9b4fa6
4 changed files with 37 additions and 2 deletions

View file

@ -3492,6 +3492,35 @@ n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
echo_i "checking maximal sized compresses bit map works ($n)"
ret=0
(
cd signer || exit 0
key1=$(${KEYGEN} -a "${DEFAULT_ALGORITHM}" -f KSK maxcbm.example)
key2=$(${KEYGEN} -a "${DEFAULT_ALGORITHM}" maxcbm.example)
cat >>maxcbm.example.db <<EOF
\$TTL 3600
@ SOA . . 0 0 0 0 3600
@ NS .
\$INCLUDE "${key1}.key"
\$INCLUDE "${key2}.key"
; the last data type in the first window
data TYPE127 \# 0
EOF
# add a record at the end of each cbm window less 1
type=$((256 + 254))
while test $type -lt 65536; do
echo "data TYPE$type \\# 0" >>maxcbm.example.db
type=$((type + 256))
done
"${SIGNER}" -3 - -o maxcbm.example maxcbm.example.db >signer.out.$n
"${CHECKZONE}" -q -D maxcbm.example maxcbm.example.db.signed \
| grep '^M7L6E3AJUD7LRVUMMQS595OGHBMT4DFT.*NSEC3.*TYPE65534$' >/dev/null || ret=1
) || ret=1
n=$((n + 1))
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "check that 'dnssec-keygen -S' works for all supported algorithms ($n)"
ret=0
alg=1

View file

@ -172,6 +172,7 @@ pytestmark = pytest.mark.extra_artifacts(
"signer/general/signed.expect",
"signer/general/signed.zone",
"signer/general/signer.out.*",
"signer/maxcbm.example.db",
"signer/nsec3param.out",
"signer/prepub.db",
"signer/revoke.example.db",

View file

@ -23,7 +23,12 @@
#include <dns/name.h>
#include <dns/types.h>
#define DNS_NSEC_BUFFERSIZE (DNS_NAME_MAXWIRE + 8192 + 512)
/*
* max compressed bitmap size:
* 256 windows * (window number + window length + bitmap (max 256 bits))
*/
#define DNS_NSEC_MAXCBMSIZE (256 * ((256 / 8) + 2))
#define DNS_NSEC_BUFFERSIZE (DNS_NAME_MAXWIRE + DNS_NSEC_MAXCBMSIZE)
ISC_LANG_BEGINDECLS

View file

@ -460,7 +460,7 @@ match_nsec3(const vctx_t *vctx, const dns_name_t *name,
const unsigned char types[8192], unsigned int maxtype,
const unsigned char *rawhash, size_t rhsize,
isc_result_t *vresult) {
unsigned char cbm[8244];
unsigned char cbm[DNS_NSEC_MAXCBMSIZE];
char namebuf[DNS_NAME_FORMATSIZE];
dns_rdata_nsec3_t nsec3;
isc_result_t result;