summaryrefslogtreecommitdiffstats
path: root/debian/patches
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 10:41:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 10:41:59 +0000
commitbe05184b2324848b4f33e6e5d9c716bc95f581f3 (patch)
tree4da6fcfe204d1694377e90c44b02f1b0790aabe8 /debian/patches
parentAdding upstream version 5.3.1. (diff)
downloadknot-resolver-be05184b2324848b4f33e6e5d9c716bc95f581f3.tar.xz
knot-resolver-be05184b2324848b4f33e6e5d9c716bc95f581f3.zip
Adding debian version 5.3.1-1+deb11u1.debian/5.3.1-1+deb11u1debian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/patches')
-rw-r--r--debian/patches/0001-treewide-fix-unaligned-access.patch117
-rw-r--r--debian/patches/0002-validator-avoid-assertion-in-an-edge-case.patch58
-rw-r--r--debian/patches/series2
3 files changed, 177 insertions, 0 deletions
diff --git a/debian/patches/0001-treewide-fix-unaligned-access.patch b/debian/patches/0001-treewide-fix-unaligned-access.patch
new file mode 100644
index 0000000..05a42ee
--- /dev/null
+++ b/debian/patches/0001-treewide-fix-unaligned-access.patch
@@ -0,0 +1,117 @@
+From ce48e5a8da49d25f5490cc1be6a54f8d9db5f520 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Vladim=C3=ADr=20=C4=8Cun=C3=A1t?= <vladimir.cunat@nic.cz>
+Date: Tue, 6 Apr 2021 17:28:52 +0200
+Subject: [PATCH] treewide: fix unaligned access
+
+Some less common HW (not x86, usually ARM) doesn't tolerate unaligned
+access to memory and it's breakage of C as well.
+
+It's easiest to check by meson's -Db_sanitize=undefined (on any HW).
+I pushed millions of real-life QNAME+QTYPE queries over UDP in default
+mode and the sanitizer seems clear now.
+---
+ lib/cache/impl.h | 16 +++++++++++-----
+ lib/cache/nsec1.c | 14 ++++++++++----
+ lib/layer/iterate.c | 4 +++-
+ lib/selection.c | 4 ++--
+ 4 files changed, 26 insertions(+), 12 deletions(-)
+
+diff --git a/lib/cache/impl.h b/lib/cache/impl.h
+index b884c361..fca8653c 100644
+--- a/lib/cache/impl.h
++++ b/lib/cache/impl.h
+@@ -45,7 +45,10 @@ struct entry_h {
+ bool has_optout : 1; /**< Only for packets; persisted DNSSEC_OPTOUT. */
+ uint8_t _pad; /**< We need even alignment for data now. */
+ uint8_t data[];
+-};
++/* Well, we don't really need packing or alignment changes,
++ * but due to LMDB the whole structure may not be stored at an aligned address,
++ * and we need compilers (for non-x86) to know it to avoid SIGBUS (test: UBSAN). */
++} __attribute__ ((packed,aligned(1)));
+ struct entry_apex;
+
+ /** Check basic consistency of entry_h for 'E' entries, not looking into ->data.
+@@ -303,10 +306,13 @@ static inline int rdataset_dematerialized_size(const uint8_t *data, uint16_t *rd
+ assert(sizeof(count) == KR_CACHE_RR_COUNT_SIZE);
+ memcpy(&count, data, sizeof(count));
+ const uint8_t *rdata = data + sizeof(count);
+- if (rdataset_count)
+- *rdataset_count = count;
+- for (int i = 0; i < count; ++i)
+- rdata += knot_rdata_size(((knot_rdata_t *)rdata)->len);
++ if (rdataset_count) // memcpy is safe for unaligned case (on non-x86)
++ memcpy(rdataset_count, &count, sizeof(count));
++ for (int i = 0; i < count; ++i) {
++ __typeof__(((knot_rdata_t *)NULL)->len) len; // memcpy as above
++ memcpy(&len, rdata + offsetof(knot_rdata_t, len), sizeof(len));
++ rdata += knot_rdata_size(len);
++ }
+ return rdata - (data + sizeof(count));
+ }
+
+diff --git a/lib/cache/nsec1.c b/lib/cache/nsec1.c
+index 3985ca3b..ed242ca8 100644
+--- a/lib/cache/nsec1.c
++++ b/lib/cache/nsec1.c
+@@ -197,8 +197,14 @@ static const char * find_leq_NSEC1(struct kr_cache *cache, const struct kr_query
+ /* We know it starts before sname, so let's check the other end.
+ * 1. construct the key for the next name - kwz_hi. */
+ /* it's *full* name ATM */
+- const knot_rdata_t *next = (const knot_rdata_t *)
+- (eh->data + KR_CACHE_RR_COUNT_SIZE);
++ /* Technical complication: memcpy is safe for unaligned case (on non-x86) */
++ __typeof__(((knot_rdata_t *)NULL)->len) next_len;
++ const uint8_t *next_data;
++ { /* next points to knot_rdata_t but possibly unaligned */
++ const uint8_t *next = eh->data + KR_CACHE_RR_COUNT_SIZE;
++ memcpy(&next_len, next + offsetof(knot_rdata_t, len), sizeof(next_len));
++ next_data = next + offsetof(knot_rdata_t, data);
++ }
+ if (KR_CACHE_RR_COUNT_SIZE != 2 || get_uint16(eh->data) == 0) {
+ assert(false);
+ return "ERROR";
+@@ -220,8 +226,8 @@ static const char * find_leq_NSEC1(struct kr_cache *cache, const struct kr_query
+ /* Lower-case chs; see also RFC 6840 5.1.
+ * LATER(optim.): we do lots of copying etc. */
+ knot_dname_t lower_buf[KNOT_DNAME_MAXLEN];
+- ret = knot_dname_to_wire(lower_buf, next->data,
+- MIN(next->len, KNOT_DNAME_MAXLEN));
++ ret = knot_dname_to_wire(lower_buf, next_data,
++ MIN(next_len, KNOT_DNAME_MAXLEN));
+ if (ret < 0) { /* _ESPACE */
+ return "range search found record with incorrect contents";
+ }
+diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c
+index 94342cfb..8fa8010e 100644
+--- a/lib/layer/iterate.c
++++ b/lib/layer/iterate.c
+@@ -132,7 +132,9 @@ static bool is_valid_addr(const uint8_t *addr, size_t len)
+ {
+ if (len == sizeof(struct in_addr)) {
+ /* Filter ANY and 127.0.0.0/8 */
+- uint32_t ip_host = ntohl(*(const uint32_t *)(addr));
++ uint32_t ip_host; /* Memcpy is safe for unaligned case (on non-x86) */
++ memcpy(&ip_host, addr, sizeof(ip_host));
++ ip_host = ntohl(ip_host);
+ if (ip_host == 0 || (ip_host & 0xff000000) == 0x7f000000) {
+ return false;
+ }
+diff --git a/lib/selection.c b/lib/selection.c
+index 56530cba..4b516bb8 100644
+--- a/lib/selection.c
++++ b/lib/selection.c
+@@ -155,8 +155,8 @@ struct rtt_state get_rtt_state(const uint8_t *ip, size_t len,
+ } else if (value.len != sizeof(struct rtt_state)) {
+ assert(false); // shouldn't happen but let's be more robust
+ state = default_rtt_state;
+- } else {
+- state = *(struct rtt_state *)value.data;
++ } else { // memcpy is safe for unaligned case (on non-x86)
++ memcpy(&state, value.data, sizeof(state));
+ }
+
+ free(key.data);
+--
+2.31.0
+
diff --git a/debian/patches/0002-validator-avoid-assertion-in-an-edge-case.patch b/debian/patches/0002-validator-avoid-assertion-in-an-edge-case.patch
new file mode 100644
index 0000000..0223c3b
--- /dev/null
+++ b/debian/patches/0002-validator-avoid-assertion-in-an-edge-case.patch
@@ -0,0 +1,58 @@
+From: =?utf-8?b?VmxhZGltw61yIMSMdW7DoXQ=?= <vladimir.cunat@nic.cz>
+Date: Mon, 12 Apr 2021 15:23:02 +0200
+Subject: [PATCH] validator: avoid assertion in an edge-case
+
+Case: NSEC3 with too many iterations used for a positive wildcard proof.
+
+To really fix the answers, this also needed fixing the `any_rank` part
+which I somehow forgot in commit 7107faebc :-(
+---
+ lib/dnssec/nsec3.c | 7 +++++++
+ lib/dnssec/nsec3.h | 1 +
+ lib/layer/validate.c | 3 ++-
+ 3 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/lib/dnssec/nsec3.c b/lib/dnssec/nsec3.c
+index e9e536a..f3a48c0 100644
+--- a/lib/dnssec/nsec3.c
++++ b/lib/dnssec/nsec3.c
+@@ -596,6 +596,13 @@ int kr_nsec3_wildcard_answer_response_check(const knot_pkt_t *pkt, knot_section_
+ if (rrset->type != KNOT_RRTYPE_NSEC3) {
+ continue;
+ }
++ if (knot_nsec3_iters(rrset->rrs.rdata) > KR_NSEC3_MAX_ITERATIONS) {
++ /* Avoid hashing with too many iterations.
++ * If we get here, the `sname` wildcard probably ends up bogus,
++ * but it gets downgraded to KR_RANK_INSECURE when validator
++ * gets to verifying one of these over-limit NSEC3 RRs. */
++ continue;
++ }
+ int ret = covers_name(&flags, rrset, sname);
+ if (ret != 0) {
+ return ret;
+diff --git a/lib/dnssec/nsec3.h b/lib/dnssec/nsec3.h
+index 1e316f5..0fdbfce 100644
+--- a/lib/dnssec/nsec3.h
++++ b/lib/dnssec/nsec3.h
+@@ -39,6 +39,7 @@ int kr_nsec3_name_error_response_check(const knot_pkt_t *pkt, knot_section_t sec
+ * KNOT_ERANGE - NSEC3 RR that covers a wildcard
+ * has been found, but has opt-out flag set;
+ * otherwise - error.
++ * Records over KR_NSEC3_MAX_ITERATIONS are skipped, so you probably get kr_error(ENOENT).
+ */
+ int kr_nsec3_wildcard_answer_response_check(const knot_pkt_t *pkt, knot_section_t section_id,
+ const knot_dname_t *sname, int trim_to_next);
+diff --git a/lib/layer/validate.c b/lib/layer/validate.c
+index cf5dda2..cf5c88a 100644
+--- a/lib/layer/validate.c
++++ b/lib/layer/validate.c
+@@ -894,7 +894,8 @@ static void rank_records(struct kr_query *qry, bool any_rank, enum kr_rank rank_
+ bailiwick) < 0) {
+ continue;
+ }
+- if (kr_rank_test(entry->rank, KR_RANK_INITIAL)
++ if (any_rank
++ || kr_rank_test(entry->rank, KR_RANK_INITIAL)
+ || kr_rank_test(entry->rank, KR_RANK_TRY)
+ || kr_rank_test(entry->rank, KR_RANK_MISSING)) {
+ kr_rank_set(&entry->rank, rank_to_set);
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..f8a7357
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,2 @@
+0001-treewide-fix-unaligned-access.patch
+0002-validator-avoid-assertion-in-an-edge-case.patch