summaryrefslogtreecommitdiffstats
path: root/debian/patches/0011-mitigate-KeyTrap-DoS-CVE-2023-50387.patch
diff options
context:
space:
mode:
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.patch80
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. */