summaryrefslogtreecommitdiffstats
path: root/debian/patches/CVE-2020-12667-part1.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/CVE-2020-12667-part1.patch')
-rw-r--r--debian/patches/CVE-2020-12667-part1.patch90
1 files changed, 90 insertions, 0 deletions
diff --git a/debian/patches/CVE-2020-12667-part1.patch b/debian/patches/CVE-2020-12667-part1.patch
new file mode 100644
index 0000000..e8505f1
--- /dev/null
+++ b/debian/patches/CVE-2020-12667-part1.patch
@@ -0,0 +1,90 @@
+From: Markus Koschany <apo@debian.org>
+Date: Mon, 11 Mar 2024 16:40:42 +0200
+Subject: CVE-2020-12667 part1
+
+Bug-Debian: https://bugs.debian.org/961076
+Origin: https://gitlab.labs.nic.cz/knot/knot-resolver/-/commit/54f05e4d7b2e47c0bdd30b84272fc503cc65304b
+---
+ daemon/lua/kres-gen.lua | 1 +
+ lib/defines.h | 1 +
+ lib/resolve.c | 15 +++++++++++----
+ lib/resolve.h | 1 +
+ 4 files changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/daemon/lua/kres-gen.lua b/daemon/lua/kres-gen.lua
+index a92288b..ad2f40e 100644
+--- a/daemon/lua/kres-gen.lua
++++ b/daemon/lua/kres-gen.lua
+@@ -200,6 +200,7 @@ struct kr_request {
+ knot_mm_t pool;
+ unsigned int uid;
+ void *daemon_context;
++ unsigned int count_no_nsaddr;
+ };
+ enum kr_rank {KR_RANK_INITIAL, KR_RANK_OMIT, KR_RANK_TRY, KR_RANK_INDET = 4, KR_RANK_BOGUS, KR_RANK_MISMATCH, KR_RANK_MISSING, KR_RANK_INSECURE, KR_RANK_AUTH = 16, KR_RANK_SECURE = 32};
+ struct kr_cache {
+diff --git a/lib/defines.h b/lib/defines.h
+index 84da059..aa3a349 100644
+--- a/lib/defines.h
++++ b/lib/defines.h
+@@ -64,6 +64,7 @@ static inline int KR_COLD kr_error(int x) {
+ #define KR_CNAME_CHAIN_LIMIT 40 /* Built-in maximum CNAME chain length */
+ #define KR_TIMEOUT_LIMIT 4 /* Maximum number of retries after timeout. */
+ #define KR_QUERY_NSRETRY_LIMIT 4 /* Maximum number of retries per query. */
++#define KR_COUNT_NO_NSADDR_LIMIT 5
+
+ /*
+ * Defines.
+diff --git a/lib/resolve.c b/lib/resolve.c
+index 65b167f..7e1f334 100644
+--- a/lib/resolve.c
++++ b/lib/resolve.c
+@@ -306,10 +306,10 @@ static int ns_fetch_cut(struct kr_query *qry, const knot_dname_t *requested_name
+ return KR_STATE_PRODUCE;
+ }
+
+-static int ns_resolve_addr(struct kr_query *qry, struct kr_request *param)
++static int ns_resolve_addr(struct kr_query *qry, struct kr_request *req)
+ {
+- struct kr_rplan *rplan = &param->rplan;
+- struct kr_context *ctx = param->ctx;
++ struct kr_rplan *rplan = &req->rplan;
++ struct kr_context *ctx = req->ctx;
+
+
+ /* Start NS queries from root, to avoid certain cases
+@@ -340,7 +340,9 @@ static int ns_resolve_addr(struct kr_query *qry, struct kr_request *param)
+ return kr_error(EAGAIN);
+ }
+ /* No IPv4 nor IPv6, flag server as unusable. */
+- VERBOSE_MSG(qry, "=> unresolvable NS address, bailing out\n");
++ ++req->count_no_nsaddr;
++ VERBOSE_MSG(qry, "=> unresolvable NS address, bailing out (counter: %u)\n",
++ req->count_no_nsaddr);
+ qry->ns.reputation |= KR_NS_NOIP4 | KR_NS_NOIP6;
+ kr_nsrep_update_rep(&qry->ns, qry->ns.reputation, ctx->cache_rep);
+ invalidate_ns(rplan, qry);
+@@ -1408,6 +1410,11 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t
+
+ ns_election:
+
++ if (unlikely(request->count_no_nsaddr >= KR_COUNT_NO_NSADDR_LIMIT)) {
++ VERBOSE_MSG(qry, "=> too many unresolvable NSs, bail out "
++ "(mitigation for NXNSAttack CVE-2020-12667)\n");
++ return KR_STATE_FAIL;
++ }
+ /* If the query has already selected a NS and is waiting for IPv4/IPv6 record,
+ * elect best address only, otherwise elect a completely new NS.
+ */
+diff --git a/lib/resolve.h b/lib/resolve.h
+index 18372a3..5900a8c 100644
+--- a/lib/resolve.h
++++ b/lib/resolve.h
+@@ -233,6 +233,7 @@ struct kr_request {
+ knot_mm_t pool;
+ unsigned int uid; /** for logging purposes only */
+ void *daemon_context; /** pointer to worker from daemon. Can be used in modules. */
++ unsigned int count_no_nsaddr;
+ };
+
+ /** Initializer for an array of *_selected. */