Remove DNS_KEYFLAG_EXTENDED

The DNS_KEYFLAG_EXTENDED flag was only legitimate for type KEY
and was eliminated by RFC 3445. Dropping the extended-flags
handling in pub_compare() also fixes a possible crash when
signing a zone whose journal contains a crafted DNSKEY: a
6-byte record with the EXTENDED bit set produced a memmove()
length that underflowed and ran off a stack buffer.
This commit is contained in:
Evan Hunt 2026-04-30 11:28:58 -07:00 committed by Ondřej Surý
parent cf18479882
commit 9c06f0a41d
No known key found for this signature in database
GPG key ID: 2820F37E873DEA41
2 changed files with 4 additions and 42 deletions

View file

@ -652,14 +652,6 @@ dst_key_todns(const dst_key_t *key, isc_buffer_t *target) {
isc_buffer_putuint8(target,
(uint8_t)dst_algorithm_tosecalg(key->key_alg));
if ((key->key_flags & DNS_KEYFLAG_EXTENDED) != 0) {
if (isc_buffer_availablelength(target) < 2) {
return ISC_R_NOSPACE;
}
isc_buffer_putuint16(
target, (uint16_t)((key->key_flags >> 16) & 0xffff));
}
if (key->keydata.generic == NULL) { /*%< NULL KEY */
return ISC_R_SUCCESS;
}
@ -671,7 +663,7 @@ isc_result_t
dst_key_fromdns(const dns_name_t *name, dns_rdataclass_t rdclass,
isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) {
uint8_t alg, proto;
uint32_t flags, extflags;
uint32_t flags;
dst_key_t *key = NULL;
dns_keytag_t id, rid;
isc_region_t r;
@ -688,14 +680,6 @@ dst_key_fromdns(const dns_name_t *name, dns_rdataclass_t rdclass,
id = dst_region_computeid(&r);
rid = dst_region_computerid(&r);
if ((flags & DNS_KEYFLAG_EXTENDED) != 0) {
if (isc_buffer_remaininglength(source) < 2) {
return DST_R_INVALIDPUBLICKEY;
}
extflags = isc_buffer_getuint16(source);
flags |= (extflags << 16);
}
RETERR(frombuffer(name, alg, flags, proto, rdclass, source, mctx,
&key));
key->key_id = id;
@ -1190,9 +1174,6 @@ pub_compare(const dst_key_t *key1, const dst_key_t *key2) {
}
/* Zero out flags. */
buf1[0] = buf1[1] = 0;
if ((key1->key_flags & DNS_KEYFLAG_EXTENDED) != 0) {
isc_buffer_subtract(&b1, 2);
}
isc_buffer_init(&b2, buf2, sizeof(buf2));
result = dst_key_todns(key2, &b2);
@ -1201,23 +1182,9 @@ pub_compare(const dst_key_t *key1, const dst_key_t *key2) {
}
/* Zero out flags. */
buf2[0] = buf2[1] = 0;
if ((key2->key_flags & DNS_KEYFLAG_EXTENDED) != 0) {
isc_buffer_subtract(&b2, 2);
}
isc_buffer_usedregion(&b1, &r1);
/* Remove extended flags. */
if ((key1->key_flags & DNS_KEYFLAG_EXTENDED) != 0) {
memmove(&buf1[4], &buf1[6], r1.length - 6);
r1.length -= 2;
}
isc_buffer_usedregion(&b2, &r2);
/* Remove extended flags. */
if ((key2->key_flags & DNS_KEYFLAG_EXTENDED) != 0) {
memmove(&buf2[4], &buf2[6], r2.length - 6);
r2.length -= 2;
}
return isc_region_compare(&r1, &r2) == 0;
}

View file

@ -26,14 +26,9 @@ enum {
DNS_KEYTYPE_NOCONF = 1 << 14, /* cannot be used for confidentiality. */
DNS_KEYFLAG_RESERVED2 = 1 << 13, /* reserved: must be zero. */
DNS_KEYFLAG_EXTENDED = 1 << 12, /* key has extended flags: if this is
* set, the first two octets of the
* key data are an additional flags
* field, at least one bit of which
* must be nonzero. (valid for KEY
* only.) */
DNS_KEYFLAG_DONOTUSE3 = 1 << 12, /* unused: must be zero.
formerly DNS_KEYFLAG_EXTENDED,
which was removed by RFC 3445 */
DNS_KEYFLAG_RESERVED4 = 1 << 11, /* reserved: must be zero. */
DNS_KEYFLAG_RESERVED5 = 1 << 10, /* reserved: must be zero. */