summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dns/dnsmasq/Makefile2
-rw-r--r--dns/dnsmasq/files/patch-zgf172fdb85
2 files changed, 86 insertions, 1 deletions
diff --git a/dns/dnsmasq/Makefile b/dns/dnsmasq/Makefile
index ba9002cb4f44..ba26d1ec62a8 100644
--- a/dns/dnsmasq/Makefile
+++ b/dns/dnsmasq/Makefile
@@ -1,7 +1,7 @@
PORTNAME= dnsmasq
DISTVERSION= 2.88
# Leave the PORTREVISION in even if 0 to avoid accidental PORTEPOCH bumps:
-PORTREVISION= 0
+PORTREVISION= 1
PORTEPOCH= 1
CATEGORIES= dns
MASTER_SITES= https://www.thekelleys.org.uk/dnsmasq/ \
diff --git a/dns/dnsmasq/files/patch-zgf172fdb b/dns/dnsmasq/files/patch-zgf172fdb
new file mode 100644
index 000000000000..f3128f57d55f
--- /dev/null
+++ b/dns/dnsmasq/files/patch-zgf172fdb
@@ -0,0 +1,85 @@
+From f172fdbb77c422e27d3b7530f3fe95b98d1608e7 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Wed, 11 Jan 2023 23:23:40 +0000
+Subject: [PATCH] Fix bug which can break the invariants on the order of a hash
+ chain.
+
+If there are multiple cache records with the same name but different
+F_REVERSE and/or F_IMMORTAL flags, the code added in fe9a134b could
+concievable break the REVERSE-FORWARD-IMMORTAL order invariant.
+
+Reproducing this is damn near impossible, but it is responsible
+for rare and otherwise inexplicable reversion between 2.87 and 2.88
+which manifests itself as a cache internal error. All observed
+cases have depended on DNSSEC being enabled, but the bug could in
+theory manifest itself without DNSSEC
+
+Thanks to Timo van Roermund for reporting the bug and huge
+efforts to isolate it.
+---
+ CHANGELOG | 16 +++++++++++++++-
+ src/cache.c | 14 +++++++++-----
+ 2 files changed, 24 insertions(+), 6 deletions(-)
+
+diff --git a/CHANGELOG b/CHANGELOG
+index 0f36a0f..d6e6753 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -1,6 +1,20 @@
++version 2.98
++ Fix bug introduced in 2.88 (commit fe91134b) which can result
++ in corruption of the DNS cache internal data structures and
++ logging of "cache internal error". This has only been seen
++ in one place in the wild, and it took considerable effort
++ to even generate a test case to reproduce it, but there's
++ no way to be sure it won't strike, and the effect to to break
++ the cache badly. Installations with DNSSEC enabled are more
++ likely to see the problem, but not running DNSSEC does not
++ guarantee that it won't happen. Thanks to Timo van Roermund
++ for reporting the bug and for his great efforts in chasing
++ it down.
++
++
+ version 2.88
+ Fix bug in --dynamic-host when an interface has /16 IPv4
+- address. Thanks to Mark Dietzer for spotting this.
++ address. Thanks to Mark Dietzer for spotting this.
+
+ Add --fast-dns-retry option. This gives dnsmasq the ability
+ to originate retries for upstream DNS queries itself, rather
+diff --git a/src/cache.c b/src/cache.c
+index 42283bc..0a5fd14 100644
+--- a/src/cache.c
++++ b/src/cache.c
+@@ -236,19 +236,23 @@ static void cache_hash(struct crec *crecp)
+
+ char *name = cache_get_name(crecp);
+ struct crec **up = hash_bucket(name);
+-
+- if (!(crecp->flags & F_REVERSE))
++ unsigned int flags = crecp->flags & (F_IMMORTAL | F_REVERSE);
++
++ if (!(flags & F_REVERSE))
+ {
+ while (*up && ((*up)->flags & F_REVERSE))
+ up = &((*up)->hash_next);
+
+- if (crecp->flags & F_IMMORTAL)
++ if (flags & F_IMMORTAL)
+ while (*up && !((*up)->flags & F_IMMORTAL))
+ up = &((*up)->hash_next);
+ }
+
+- /* Preserve order when inserting the same name multiple times. */
+- while (*up && hostname_isequal(cache_get_name(*up), name))
++ /* Preserve order when inserting the same name multiple times.
++ Do not mess up the flag invariants. */
++ while (*up &&
++ hostname_isequal(cache_get_name(*up), name) &&
++ flags == ((*up)->flags & (F_IMMORTAL | F_REVERSE)))
+ up = &((*up)->hash_next);
+
+ crecp->hash_next = *up;
+--
+2.20.1
+