diff options
Diffstat (limited to 'meta-networking/recipes-support/dnsmasq/files/CVE-2020-25684.patch')
-rw-r--r-- | meta-networking/recipes-support/dnsmasq/files/CVE-2020-25684.patch | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/meta-networking/recipes-support/dnsmasq/files/CVE-2020-25684.patch b/meta-networking/recipes-support/dnsmasq/files/CVE-2020-25684.patch new file mode 100644 index 0000000000..f7ff4b27cc --- /dev/null +++ b/meta-networking/recipes-support/dnsmasq/files/CVE-2020-25684.patch @@ -0,0 +1,98 @@ +From 257ac0c5f7732cbc6aa96fdd3b06602234593aca Mon Sep 17 00:00:00 2001 +From: Simon Kelley <simon@thekelleys.org.uk> +Date: Thu, 12 Nov 2020 18:49:23 +0000 +Subject: [PATCH] Check destination of DNS UDP query replies. + +At any time, dnsmasq will have a set of sockets open, bound to +random ports, on which it sends queries to upstream nameservers. +This patch fixes the existing problem that a reply for ANY in-flight +query would be accepted via ANY open port, which increases the +chances of an attacker flooding answers "in the blind" in an +attempt to poison the DNS cache. CERT VU#434904 refers. + +Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com> +--- + CHANGELOG | 6 +++++- + src/forward.c | 37 ++++++++++++++++++++++++++++--------- + 2 files changed, 33 insertions(+), 10 deletions(-) + +CVE: CVE-2020-25684 +Upstream-Status: Backport [https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=patch;h=257ac0c5f7732cbc6aa96fdd3b06602234593aca] +Comment: No change in any hunk + +Index: dnsmasq-2.81/src/forward.c +=================================================================== +--- dnsmasq-2.81.orig/src/forward.c ++++ dnsmasq-2.81/src/forward.c +@@ -16,7 +16,7 @@ + + #include "dnsmasq.h" + +-static struct frec *lookup_frec(unsigned short id, void *hash); ++static struct frec *lookup_frec(unsigned short id, int fd, int family, void *hash); + static struct frec *lookup_frec_by_sender(unsigned short id, + union mysockaddr *addr, + void *hash); +@@ -805,7 +805,7 @@ void reply_query(int fd, int family, tim + crc = questions_crc(header, n, daemon->namebuff); + #endif + +- if (!(forward = lookup_frec(ntohs(header->id), hash))) ++ if (!(forward = lookup_frec(ntohs(header->id), fd, family, hash))) + return; + + #ifdef HAVE_DUMPFILE +@@ -2338,14 +2338,25 @@ struct frec *get_new_frec(time_t now, in + } + + /* crc is all-ones if not known. */ +-static struct frec *lookup_frec(unsigned short id, void *hash) ++static struct frec *lookup_frec(unsigned short id, int fd, int family, void *hash) + { + struct frec *f; + + for(f = daemon->frec_list; f; f = f->next) + if (f->sentto && f->new_id == id && + (!hash || memcmp(hash, f->hash, HASH_SIZE) == 0)) +- return f; ++ { ++ /* sent from random port */ ++ if (family == AF_INET && f->rfd4 && f->rfd4->fd == fd) ++ return f; ++ ++ if (family == AF_INET6 && f->rfd6 && f->rfd6->fd == fd) ++ return f; ++ ++ /* sent to upstream from bound socket. */ ++ if (f->sentto->sfd && f->sentto->sfd->fd == fd) ++ return f; ++ } + + return NULL; + } +@@ -2406,12 +2417,20 @@ void server_gone(struct server *server) + static unsigned short get_id(void) + { + unsigned short ret = 0; ++ struct frec *f; + +- do +- ret = rand16(); +- while (lookup_frec(ret, NULL)); +- +- return ret; ++ while (1) ++ { ++ ret = rand16(); ++ ++ /* ensure id is unique. */ ++ for (f = daemon->frec_list; f; f = f->next) ++ if (f->sentto && f->new_id == ret) ++ break; ++ ++ if (!f) ++ return ret; ++ } + } + + |