diff options
Diffstat (limited to 'debian/patches/CVE-2020-12667-part1.patch')
-rw-r--r-- | debian/patches/CVE-2020-12667-part1.patch | 90 |
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 = ¶m->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. */ |