From 754177b36803628cf6999c0cfd0b9c424c76281b Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Sat, 16 May 2026 23:26:56 +0100 Subject: [PATCH] Fix hostname_issubdomain() confusion. commit 1269f074f86bb959863012063060a3a082d37dc4 broke hostname_issubdomain() and then accidentally fixed some of the problems by inverting the argument order in the new uses of the function it introduced. All the pre-existing calls to hostname_issubdomain() were left in a non-working state. This fixes hostname_issubdomain() back to the state before 1269f074f86bb959863012063060a3a082d37dc4, adds some logic to give correct answers when comparing to the root domain, and gets right the new calls to hostname_issubdomain() added in 1269f074f86bb959863012063060a3a082d37dc4 Thanks to Jean Thomas for spotting this problem. --- src/dnssec.c | 6 +++--- src/util.c | 17 ++++++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/dnssec.c b/src/dnssec.c index 8c77098..a503fcd 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -383,7 +383,7 @@ static int explore_rrset(struct dns_header *header, size_t plen, int class, int an attacker using signatures made with the key of an unrelated zone he controls. Note that the root key is always allowed. Ignore sigs which aren't valid */ - if (*daemon->workspacename == 0 || hostname_issubdomain(name, daemon->workspacename) != 0) + if (*daemon->workspacename == 0 || hostname_issubdomain(daemon->workspacename, name) != 0) { if (gotkey) { @@ -2095,8 +2095,8 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch CNAME must be . CNAME target must be . s must match for name and target. */ - if (hostname_issubdomain(daemon->cname, name) == 1 && - hostname_issubdomain(daemon->workspacename, keyname) == 1 && + if (hostname_issubdomain(name, daemon->cname) == 1 && + hostname_issubdomain(keyname, daemon->workspacename) == 1 && name_prefix_len == strlen(daemon->workspacename) - strlen(keyname)) { char save = daemon->cname[name_prefix_len]; diff --git a/src/util.c b/src/util.c index b41b7c1..1d98951 100644 --- a/src/util.c +++ b/src/util.c @@ -439,10 +439,14 @@ int hostname_issubdomain(char *a, char *b) for (ap = a; *ap; ap++); for (bp = b; *bp; bp++); - /* a shorter than b */ - if ((ap - a) < (bp - b)) + /* anything is a subdomain of the root domain. */ + if (ap == a) + return (bp == b) ? 2 : 1; + + /* b shorter than a */ + if ((bp - b) < (ap - a)) return 0; - + do { c1 = (unsigned char) *(--ap); @@ -455,18 +459,17 @@ int hostname_issubdomain(char *a, char *b) if (c1 != c2) return 0; - } while (bp != b); + } while (ap != a); - if (ap == a) + if (bp == b) return 2; - if (*(--ap) == '.') + if (*(--bp) == '.') return 1; return 0; } - time_t dnsmasq_time(void) { #ifdef HAVE_BROKEN_RTC