diff options
author | William Pitcock <nenolod@dereferenced.org> | 2018-03-31 09:31:12 +0000 |
---|---|---|
committer | William Pitcock <nenolod@dereferenced.org> | 2018-03-31 09:41:28 +0000 |
commit | 304973c00a58325b7b558d739d0310a68aac4e8c (patch) | |
tree | 951cf7cdd79bc5d7cce6a8096a524ed118945324 /main/musl | |
parent | 2a7c4929a55ef47f72fe49f9c1aa62c29857557d (diff) | |
download | aports-304973c00a58325b7b558d739d0310a68aac4e8c.tar.bz2 aports-304973c00a58325b7b558d739d0310a68aac4e8c.tar.xz |
main/musl: update k8s + cloudflare mitigation patch to latest proposed version
this version will only activate itself under a relevant configuration where the cloudflare
DNS problem is harmful
Diffstat (limited to 'main/musl')
-rw-r--r-- | main/musl/1000-cloudflare-stupidity.patch | 139 | ||||
-rw-r--r-- | main/musl/APKBUILD | 4 |
2 files changed, 125 insertions, 18 deletions
diff --git a/main/musl/1000-cloudflare-stupidity.patch b/main/musl/1000-cloudflare-stupidity.patch index 118b03794a..5cb9360c2d 100644 --- a/main/musl/1000-cloudflare-stupidity.patch +++ b/main/musl/1000-cloudflare-stupidity.patch @@ -1,31 +1,138 @@ -From 86e97abb42cd88046c594f6b3baa07081bbcdf13 Mon Sep 17 00:00:00 2001 +From 544b7fd44079df6eb5ae4f416e73b8e51602c2bb Mon Sep 17 00:00:00 2001 From: William Pitcock <nenolod@dereferenced.org> -Date: Fri, 30 Mar 2018 18:48:53 +0000 -Subject: [PATCH] resolver: only exit the search path loop there are a positive - number of results given +Date: Sat, 31 Mar 2018 09:16:16 +0000 +Subject: [PATCH] resolver: mitigate bad interactions concering inconsistent + DNS search domains with ndots usage -In the event of no results being given by any of the lookup modules, EAI_NONAME will still -be thrown. +When using kubernetes, the search path is configured like so: -This is intended to mitigate problems that occur when zones are hosted by weird DNS servers, -such as the one Cloudflare have implemented, and appear in the search path. + - containername.prod.env.whatever + - prod.env.whatever + - env.whatever + - clusterwide domain + +Kubernetes also typically configures the container's resolver with "options ndots:5", which +causes it to look for public domains in the private DNS domains (presumably so their DNS +records can be overridden somehow). + +In certain cases where the Kubernetes guest is configured with a clusterwide domain that is +hosted by a certain large CDN provider (*ahem* Cloudflare), the resolver may process +erroneous replies sent from that CDN provider that have an empty A/AAAA record set. + +Accordingly, if we detect a configuration that is exotic, as a mitigation, we force all DNS +queries to behave as if they were AF_UNSPEC and return only the records that were actually +requested (either A or AAAA). --- - src/network/lookup_name.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + src/network/lookup_name.c | 35 ++++++++++++++++++++++++++++++----- + 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c -index 209c20f0..b068bb92 100644 +index 209c20f0..b28b6208 100644 --- a/src/network/lookup_name.c +++ b/src/network/lookup_name.c -@@ -202,7 +202,7 @@ static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[ +@@ -95,7 +95,9 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati + struct dpc_ctx { + struct address *addrs; + char *canon; ++ int wanted; + int cnt; ++ int recordcnt[2]; + }; + + int __dns_parse(const unsigned char *, int, int (*)(void *, int, const void *, int, const void *), void *); +@@ -115,12 +117,16 @@ static int dns_parse_callback(void *c, int rr, const void *data, int len, const + switch (rr) { + case RR_A: + if (len != 4) return -1; ++ ctx->recordcnt[0]++; ++ if (ctx->wanted && rr != ctx->wanted) return 0; + ctx->addrs[ctx->cnt].family = AF_INET; + ctx->addrs[ctx->cnt].scopeid = 0; + memcpy(ctx->addrs[ctx->cnt++].addr, data, 4); + break; + case RR_AAAA: + if (len != 16) return -1; ++ ctx->recordcnt[1]++; ++ if (ctx->wanted && rr != ctx->wanted) return 0; + ctx->addrs[ctx->cnt].family = AF_INET6; + ctx->addrs[ctx->cnt].scopeid = 0; + memcpy(ctx->addrs[ctx->cnt++].addr, data, 16); +@@ -134,7 +140,7 @@ static int dns_parse_callback(void *c, int rr, const void *data, int len, const + return 0; + } + +-static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, const struct resolvconf *conf) ++static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, const struct resolvconf *conf, int searchpath_len) + { + unsigned char qbuf[2][280], abuf[2][512]; + const unsigned char *qp[2] = { qbuf[0], qbuf[1] }; +@@ -148,7 +154,12 @@ static int name_from_dns(struct address buf[static MAXADDRS], char canon[static + }; + + for (i=0; i<2; i++) { +- if (family != afrr[i].af) { ++ if (family && family != afrr[i].af) ctx.wanted = afrr[i].rr; ++ ++ /* If we are using search paths longer than 1 domain, or we have changed the ++ * ndots setting to be greater than 1, then we need to always treat the query ++ * as if it were AF_UNSPEC to ensure results are consistent. */ ++ if (family != afrr[i].af || searchpath_len > 1 || conf->ndots > 1) { + qlens[nq] = __res_mkquery(0, name, 1, afrr[i].rr, + 0, 0, 0, qbuf[nq], sizeof *qbuf); + if (qlens[nq] == -1) +@@ -165,7 +176,14 @@ static int name_from_dns(struct address buf[static MAXADDRS], char canon[static + + if (ctx.cnt) return ctx.cnt; + if (alens[0] < 4 || (abuf[0][3] & 15) == 2) return EAI_AGAIN; +- if ((abuf[0][3] & 15) == 0) return EAI_NONAME; ++ if ((abuf[0][3] & 15) == 0) { ++ /* A certain large CDN provider's DNS service erroneously responds to queries with ++ * a NOERROR(0) response code, while also returning an empty record set. Accordingly, ++ * check for this and handle it as we would an NXDOMAIN(3) if the record set is empty ++ * for both A and AAAA records. */ ++ if (nq == 2 && (ctx.recordcnt[0] + ctx.recordcnt[1]) == 0) return 0; ++ else return EAI_NONAME; ++ } + if ((abuf[0][3] & 15) == 3) return 0; + return EAI_FAIL; + } +@@ -175,6 +193,7 @@ static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[ + char search[256]; + struct resolvconf conf; + size_t l, dots; ++ int searchpath_len = 0; + char *p, *z; + + if (__get_resolv_conf(&conf, search, sizeof search) < 0) return -1; +@@ -184,6 +203,12 @@ static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[ + for (dots=l=0; name[l]; l++) if (name[l]=='.') dots++; + if (dots >= conf.ndots || name[l-1]=='.') *search = 0; + ++ /* Count the number of domains in the search path. */ ++ if (*search) { ++ size_t n; ++ for (searchpath_len = n = 0; search[n]; n++) if (isspace(search[n])) searchpath_len++; ++ } ++ + /* This can never happen; the caller already checked length. */ + if (l >= 256) return EAI_NONAME; + +@@ -201,13 +226,13 @@ static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[ + if (z-p < 256 - l - 1) { memcpy(canon+l+1, p, z-p); canon[z-p+1+l] = 0; - int cnt = name_from_dns(buf, canon, canon, family, &conf); -- if (cnt) return cnt; -+ if (cnt > 0) return cnt; +- int cnt = name_from_dns(buf, canon, canon, family, &conf); ++ int cnt = name_from_dns(buf, canon, canon, family, &conf, searchpath_len); + if (cnt) return cnt; } } + canon[l] = 0; +- return name_from_dns(buf, canon, name, family, &conf); ++ return name_from_dns(buf, canon, name, family, &conf, searchpath_len); + } + + static const struct policy { -- -2.16.2 +2.16.3 diff --git a/main/musl/APKBUILD b/main/musl/APKBUILD index 6376f45f35..8ecd2eb6e0 100644 --- a/main/musl/APKBUILD +++ b/main/musl/APKBUILD @@ -2,7 +2,7 @@ # Maintainer: Timo Teräs <timo.teras@iki.fi> pkgname=musl pkgver=1.1.19 -pkgrel=3 +pkgrel=4 pkgdesc="the musl c library (libc) implementation" url="http://www.musl-libc.org/" arch="all" @@ -149,7 +149,7 @@ compat() { sha512sums="abee52d53af4b3c14c9088866c911a24d2b6ef67dc494f38a7a09dfe77250026f77528c24c52469c89cffa8ced2f0fa95badbdcf8d4460c90faba47e3927bcc5 musl-1.1.19.tar.gz 7a6480c454ad25d156727818cf61961880e526abcb00382ed81e40256ac5b06af546837652e47187132d64c261d9f01ce91a952762afd439a8faf5825306a880 0001-fix-getopt-wrongly-treating-colons-in-optstring-as-v.patch 1c649ebd4814ee22364d8766fdf93732e0c0c54361fcfcc994be254b52e9beb276fca5031a1cef9d4f971c96dc3d3774a1738ba3a38263d8e139ea3947c9b7c3 0002-fix-nl_langinfo_l-CODESET-loc-reporting-wrong-locale.patch -86ba902f640fe3a64ad0c3892c14bf8425ca322025f922ef9debb4d52227f929ccb0a8f29986321b3b6da601ea1b6dd291359cbf8cd9a6dba7aa572e9000fa67 1000-cloudflare-stupidity.patch +26465058345bcb0d8f5ebd4645b43b2cb3dec26ac55f8cb97a13961f28046fe04bd68e48ba585cc3c036ba75e3cabadf096595e71d1c8c9ec0fb69ebc8340cf5 1000-cloudflare-stupidity.patch 2c8e1dde1834238097b2ee8a7bfb53471a0d9cff4a5e38b55f048b567deff1cdd47c170d0578a67b1a039f95a6c5fbb8cff369c75b6a3e4d7ed171e8e86ebb8c 2000-pthread-internals-increase-DEFAULT_GUARD_SIZE-to-2-p.patch 6a7ff16d95b5d1be77e0a0fbb245491817db192176496a57b22ab037637d97a185ea0b0d19da687da66c2a2f5578e4343d230f399d49fe377d8f008410974238 handle-aux-at_base.patch 8d3a2d5315fc56fee7da9abb8b89bb38c6046c33d154c10d168fb35bfde6b0cf9f13042a3bceee34daf091bc409d699223735dcf19f382eeee1f6be34154f26f ldconfig |