summaryrefslogtreecommitdiffstats
path: root/debian/patches/CVE-2020-12667-part2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/CVE-2020-12667-part2.patch')
-rw-r--r--debian/patches/CVE-2020-12667-part2.patch86
1 files changed, 86 insertions, 0 deletions
diff --git a/debian/patches/CVE-2020-12667-part2.patch b/debian/patches/CVE-2020-12667-part2.patch
new file mode 100644
index 0000000..7ca9173
--- /dev/null
+++ b/debian/patches/CVE-2020-12667-part2.patch
@@ -0,0 +1,86 @@
+From: Markus Koschany <apo@debian.org>
+Date: Mon, 11 Mar 2024 16:41:21 +0200
+Subject: CVE-2020-12667 part2
+
+Bug-Debian: https://bugs.debian.org/961076
+Origin: https://gitlab.labs.nic.cz/knot/knot-resolver/-/commit/ba7b89db780fe3884b4e90090318e25ee5afb118
+---
+ daemon/lua/kres-gen.lua | 1 +
+ lib/defines.h | 1 +
+ lib/layer/iterate.c | 3 ++-
+ lib/resolve.c | 11 +++++++++++
+ lib/resolve.h | 1 +
+ 5 files changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/daemon/lua/kres-gen.lua b/daemon/lua/kres-gen.lua
+index ad2f40e..5867f0f 100644
+--- a/daemon/lua/kres-gen.lua
++++ b/daemon/lua/kres-gen.lua
+@@ -201,6 +201,7 @@ struct kr_request {
+ unsigned int uid;
+ void *daemon_context;
+ unsigned int count_no_nsaddr;
++ unsigned int count_fail_row;
+ };
+ 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 aa3a349..2eee6cf 100644
+--- a/lib/defines.h
++++ b/lib/defines.h
+@@ -65,6 +65,7 @@ static inline int KR_COLD kr_error(int x) {
+ #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
++#define KR_CONSUME_FAIL_ROW_LIMIT 3 /* Maximum number of KR_STATE_FAIL in a row. */
+
+ /*
+ * Defines.
+diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c
+index 0423a3d..40087a1 100644
+--- a/lib/layer/iterate.c
++++ b/lib/layer/iterate.c
+@@ -875,7 +875,8 @@ static int process_stub(knot_pkt_t *pkt, struct kr_request *req)
+ }
+
+
+-/** Error handling, RFC1034 5.3.3, 4d. */
++/** Error handling, RFC1034 5.3.3, 4d.
++ * NOTE: returing this does not prevent further queries (by itself). */
+ static int resolve_error(knot_pkt_t *pkt, struct kr_request *req)
+ {
+ return KR_STATE_FAIL;
+diff --git a/lib/resolve.c b/lib/resolve.c
+index 7e1f334..fbe1aab 100644
+--- a/lib/resolve.c
++++ b/lib/resolve.c
+@@ -951,6 +951,17 @@ int kr_resolve_consume(struct kr_request *request, const struct sockaddr *src, k
+ qry->flags.RESOLVED = false;
+ }
+
++ /* For multiple errors in a row; invalidate_ns() is not enough. */
++ if (!qry->flags.CACHED) {
++ if (request->state & KR_STATE_FAIL) {
++ if (++request->count_fail_row > KR_CONSUME_FAIL_ROW_LIMIT) {
++ return KR_STATE_FAIL;
++ }
++ } else {
++ request->count_fail_row = 0;
++ }
++ }
++
+ /* Pop query if resolved. */
+ if (request->state == KR_STATE_YIELD) {
+ return KR_STATE_PRODUCE; /* Requery */
+diff --git a/lib/resolve.h b/lib/resolve.h
+index 5900a8c..4d8b385 100644
+--- a/lib/resolve.h
++++ b/lib/resolve.h
+@@ -234,6 +234,7 @@ struct kr_request {
+ 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;
++ unsigned int count_fail_row;
+ };
+
+ /** Initializer for an array of *_selected. */