@@ -21,6 +21,7 @@ SRC_URI = "http://www.thekelleys.org.uk/dnsmasq/${@['archive/', ''][float(d.getV
file://CVE-2026-4893.patch \
file://CVE-2026-5172.patch \
file://CVE-2026-2291.patch \
+ file://CVE-2026-12725.patch \
"
SRC_URI[sha256sum] = "8f6666b542403b5ee7ccce66ea73a4a51cf19dd49392aaccd37231a2c51b303b"
new file mode 100644
@@ -0,0 +1,111 @@
+From 85a8577cc28751a2337275e566a9e29b8e8d8403 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Tue, 21 Apr 2026 22:14:41 +0100
+Subject: [PATCH] Fix buffer overlow in log_query()
+
+The addition of "(not supported)" to logs of DS and DNSKEY replies
+overflows the buffer used to construct the string.
+
+Re-arrange things to avoid this, and add checks to avoid the same problem
+if the logging calls change in the future.
+
+Thanks to Yiwei Hou for finding this.
+
+The problem exists is DNSSEC is enabled and query logging is also
+enabled. The overwrite is of bounded length and the bytes
+written are not in control of an attacker, so this is not considered
+a likely remote-execution vector.
+
+CVE: CVE-2026-12725
+Upstream-Status: Backport [https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=36d081e37477027fd721fea498f3760f529034ad]
+
+Backport Changes:
+- dnsmasq 2.90 predates upstream commit 9e67099ce73c, which added
+ F_QUERY to the log_query() type-string exclusion mask. Preserve the
+ existing 2.90 F_QUERY logging behavior and add only the
+ security-relevant F_KEYTAG and F_RR exclusions.
+
+(cherry picked from commit 36d081e37477027fd721fea498f3760f529034ad)
+Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
+---
+ src/cache.c | 28 +++++++++++++++++-----------
+ src/dnssec.c | 7 ++-----
+ 2 files changed, 19 insertions(+), 16 deletions(-)
+
+diff --git a/src/cache.c b/src/cache.c
+index 0eacec9..5f92520 100644
+--- a/src/cache.c
++++ b/src/cache.c
+@@ -2104,7 +2104,7 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
+ return;
+
+ /* build query type string if requested */
+- if (!(flags & (F_SERVER | F_IPSET)) && type > 0)
++ if (!(flags & (F_SERVER | F_IPSET | F_KEYTAG | F_RR)) && type > 0)
+ arg = querystr(arg, type);
+
+ dest = arg;
+@@ -2120,19 +2120,25 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
+ {
+ dest = daemon->addrbuff;
+
+- if (flags & F_RR)
+- {
+- if (flags & F_KEYTAG)
+- dest = querystr(NULL, addr->rrblock.rrtype);
+- else
+- dest = querystr(NULL, addr->rrdata.rrtype);
+- }
+- else if (flags & F_KEYTAG)
+- sprintf(daemon->addrbuff, arg, addr->log.keytag, addr->log.algo, addr->log.digest);
++ if (flags & F_RR)
++ {
++ if (flags & F_KEYTAG)
++ dest = querystr(NULL, addr->rrblock.rrtype);
++ else
++ dest = querystr(NULL, addr->rrdata.rrtype);
++ }
++#ifdef HAVE_DNSSEC
++ else if (flags & F_KEYTAG)
++ {
++ snprintf(daemon->addrbuff, ADDRSTRLEN, arg, addr->log.keytag, addr->log.algo, addr->log.digest);
++ if (type)
++ extra = " (not supported)";
++ }
++#endif
+ else if (flags & F_RCODE)
+ {
+ unsigned int rcode = addr->log.rcode;
+-
++
+ if (rcode == SERVFAIL)
+ dest = "SERVFAIL";
+ else if (rcode == REFUSED)
+diff --git a/src/dnssec.c b/src/dnssec.c
+index bdd48ca..28c07dd 100644
+--- a/src/dnssec.c
++++ b/src/dnssec.c
+@@ -953,10 +953,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
+
+ a.log.keytag = keytag;
+ a.log.algo = algo;
+- if (algo_digest_name(algo))
+- log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu", 0);
+- else
+- log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu (not supported)", 0);
++ log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu", !algo_digest_name(algo));
+ }
+ }
+
+@@ -1082,7 +1079,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
+ a.log.keytag = keytag;
+ a.log.algo = algo;
+ a.log.digest = digest;
+- log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS for keytag %hu, algo %hu, digest %hu (not supported)", 0);
++ log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS for keytag %hu, algo %hu, digest %hu", 1);
+ neg_ttl = ttl;
+ }
+ else if ((key = blockdata_alloc((char*)p, rdlen - 4)))
+--
+2.44.4
+