diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 10:41:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 10:41:59 +0000 |
commit | be05184b2324848b4f33e6e5d9c716bc95f581f3 (patch) | |
tree | 4da6fcfe204d1694377e90c44b02f1b0790aabe8 /debian/patches | |
parent | Adding upstream version 5.3.1. (diff) | |
download | knot-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.patch | 117 | ||||
-rw-r--r-- | debian/patches/0002-validator-avoid-assertion-in-an-edge-case.patch | 58 | ||||
-rw-r--r-- | debian/patches/series | 2 |
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 |