]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Tidy up cleanup path in check_signer() 11960/head
authorOndřej Surý <ondrej@sury.org>
Fri, 10 Apr 2026 16:25:18 +0000 (18:25 +0200)
committerOndřej Surý <ondrej@sury.org>
Tue, 5 May 2026 06:24:46 +0000 (08:24 +0200)
The cloned signature rdataset was not disassociated on the early
return taken when dns_dnssec_keyfromrdata() fails to parse the DNSKEY
public-key data.  In every current caller val->sigrdataset reaches
check_signer() rdatalist-backed, so dns_rdataset_clone() copies the
struct without taking any reference and dns_rdataset_disassociate()
is a no-op -- no memory is actually leaked today.  Hoist the key
parse out of the per-RRSIG loop and let the function fall through
to a single cleanup path, so the parse and the iteration cannot
diverge again.

Assisted-by: Claude:claude-opus-4-7
(cherry picked from commit 19f44a0aa376bace89d8ffaece546e1fc891a763)

lib/dns/validator.c

index 3ea4a640aecba1dcaeee963825c0d6bf05309007..44ff5a2094c568afc80b17a0c61e2d6d2144fcb4 100644 (file)
@@ -1730,6 +1730,12 @@ check_signer(dns_validator_t *val, dns_rdata_t *keyrdata, uint16_t keyid,
        isc_result_t result;
        dns_rdataset_t rdataset = DNS_RDATASET_INIT;
 
+       result = dns_dnssec_keyfromrdata(val->event->name, keyrdata,
+                                        val->view->mctx, &dstkey);
+       if (result != ISC_R_SUCCESS) {
+               return result;
+       }
+
        dns_rdataset_clone(val->event->sigrdataset, &rdataset);
 
        for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
@@ -1743,23 +1749,14 @@ check_signer(dns_validator_t *val, dns_rdata_t *keyrdata, uint16_t keyid,
                if (keyid != sig.keyid || algorithm != sig.algorithm) {
                        continue;
                }
-               if (dstkey == NULL) {
-                       result = dns_dnssec_keyfromrdata(
-                               val->event->name, keyrdata, val->view->mctx,
-                               &dstkey);
-                       if (result != ISC_R_SUCCESS) {
-                               return result;
-                       }
-               }
+
                result = verify(val, dstkey, &rdata, sig.keyid);
                if (result == ISC_R_SUCCESS) {
                        break;
                }
        }
 
-       if (dstkey != NULL) {
-               dst_key_free(&dstkey);
-       }
+       dst_key_free(&dstkey);
        dns_rdataset_disassociate(&rdataset);
 
        return result;