diff options
Diffstat (limited to 'debian/patches/0011-mitigate-KeyTrap-DoS-CVE-2023-50387.patch')
-rw-r--r-- | debian/patches/0011-mitigate-KeyTrap-DoS-CVE-2023-50387.patch | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/debian/patches/0011-mitigate-KeyTrap-DoS-CVE-2023-50387.patch b/debian/patches/0011-mitigate-KeyTrap-DoS-CVE-2023-50387.patch new file mode 100644 index 0000000..e074a94 --- /dev/null +++ b/debian/patches/0011-mitigate-KeyTrap-DoS-CVE-2023-50387.patch @@ -0,0 +1,80 @@ +From: =?utf-8?b?VmxhZGltw61yIMSMdW7DoXQ=?= <vladimir.cunat@nic.cz> +Date: Tue, 16 Jan 2024 07:35:20 +0100 +Subject: mitigate KeyTrap DoS = CVE-2023-50387 + +Improve: don't retry in this case. +--- + lib/dnssec.c | 7 ++++--- + lib/layer/validate.c | 4 ++++ + lib/resolve.c | 4 +++- + 3 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/lib/dnssec.c b/lib/dnssec.c +index 1e6eb58..262570c 100644 +--- a/lib/dnssec.c ++++ b/lib/dnssec.c +@@ -134,7 +134,7 @@ int kr_rrset_validate(kr_rrset_validation_ctx_t *vctx, knot_rrset_t *covered) + memset(&vctx->rrs_counters, 0, sizeof(vctx->rrs_counters)); + for (unsigned i = 0; i < vctx->keys->rrs.count; ++i) { + int ret = kr_rrset_validate_with_key(vctx, covered, i, NULL); +- if (ret == 0) { ++ if (ret == 0 || ret == kr_error(E2BIG)) { + return ret; + } + } +@@ -307,7 +307,7 @@ int kr_svldr_rrset(knot_rrset_t *rrs, const knot_rdataset_t *rrsigs, + } + for (ssize_t i = 0; i < ctx->keys.len; ++i) { + kr_svldr_rrset_with_key(rrs, rrsigs, &ctx->vctx, &ctx->keys.at[i]); +- if (ctx->vctx.result == 0) ++ if (ctx->vctx.result == 0 || ctx->vctx.result == kr_error(E2BIG)) + break; + } + return ctx->vctx.result; +@@ -393,6 +393,7 @@ static int kr_rrset_validate_with_key(kr_rrset_validation_ctx_t *vctx, + } + } + if (!check_crypto_limit(vctx)) { ++ vctx->result = kr_error(E2BIG); + goto finish; + } + if (kr_check_signature(rdata_j, key, covered, trim_labels) != 0) { +@@ -475,7 +476,7 @@ int kr_dnskeys_trusted(kr_rrset_validation_ctx_t *vctx, const knot_rdataset_t *s + if (ret == 0) + ret = kr_svldr_rrset_with_key(keys, sigs, vctx, &key); + svldr_key_del(&key); +- if (ret == 0) { ++ if (ret == 0 || ret == kr_error(E2BIG)) { + kr_assert(vctx->result == 0); + return vctx->result; + } +diff --git a/lib/layer/validate.c b/lib/layer/validate.c +index 4882da8..1fdc57d 100644 +--- a/lib/layer/validate.c ++++ b/lib/layer/validate.c +@@ -1177,6 +1177,10 @@ static int validate(kr_layer_t *ctx, knot_pkt_t *pkt) + ret = validate_records(req, pkt, req->rplan.pool, has_nsec3); + if (ret == KNOT_EDOWNGRADED) { + return KR_STATE_DONE; ++ } else if (ret == kr_error(E2BIG)) { ++ qry->flags.DNSSEC_BOGUS = true; ++ return KR_STATE_FAIL; ++ + } else if (ret != 0) { + /* something exceptional - no DNS key, empty pointers etc + * normally it shouldn't happen */ +diff --git a/lib/resolve.c b/lib/resolve.c +index 9e82e6f..456065b 100644 +--- a/lib/resolve.c ++++ b/lib/resolve.c +@@ -880,7 +880,9 @@ int kr_resolve_consume(struct kr_request *request, struct kr_transport **transpo + + /* Do not finish with bogus answer. */ + if (qry->flags.DNSSEC_BOGUS) { +- if (qry->flags.FORWARD || qry->flags.STUB) { ++ if (qry->flags.FORWARD || qry->flags.STUB ++ /* Probably CPU exhaustion attempt, so do not retry. */ ++ || qry->vld_limit_crypto_remains <= 0) { + return KR_STATE_FAIL; + } + /* Other servers might not have broken DNSSEC. */ |