public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/dnsmasq] rawhide: Update to 2.93 (rbhz#2484748)
@ 2026-07-03 16:54 
  0 siblings, 0 replies; only message in thread
From:  @ 2026-07-03 16:54 UTC (permalink / raw)
  To: git-commits

            A new commit has been pushed.

            Repo   : rpms/dnsmasq
            Branch : rawhide
            Commit : 0cf59fd963af677c2277d467feb052dcf6ab00c2
            Author : Petr Menšík <pemensik@redhat.com>
            Date   : 2026-07-02T16:45:02+02:00
            Stats  : +9/-600 in 6 file(s)
            URL    : https://src.fedoraproject.org/rpms/dnsmasq/c/0cf59fd963af677c2277d467feb052dcf6ab00c2?branch=rawhide

            Log:
            Update to 2.93 (rbhz#2484748)

version 2.93
	Fix a corner-case in DNSSEC validation with wildcards. If we have
	a wildcard record *.example.com and receive a query for
	a.example.com then that's OK, but we have to check that there isn't
	an actual a.example.com record. The corner case is when we get a
	query for *.example.com in that case the non-existence check
	is not required, was being done. Thanks to Jan Breig for
	spotting this.

	Enable support for inotify on FreeBSD 15.0-RELEASE, which added
	Linux-compatible inotify support.

	Fix DNSSEC failure with spurious RRSIGs. The presence of wrong
	RRSIG RRs in replies caused DNSSEC validation to fail even
	when the RRs do not require validation because the zone is
	unsigned. Note that, at the time of this commit, Google
	DNS appears to have the same bug, so if you're using 8.8.8.8
	or friends as upstream, resolving the broken zones
	(eg rivcoed.org) will still fail. Thanks to Petr Menšík
	for the bug report.

	Fix DNSSEC fail with CNAME replies to DS queries. A CNAME reply
	to a DNSSEC query was confusing the validation logic. It now
	accepts a signed CNAME reply to a DS query as proof that no DS
	exists at the domain. This fixes the DS/zone break detection logic.

	Fix regression in 2.92 release which broke DHCPv6 when a DHCP
	relay is in use. Many thanks to Jørgen Søvik for help
	finding this bug.

	Modify the inotify implementation so that inotify watches are
	only created after dnsmasq has changed permissions and userid.
	This means that the permissions used when creating the watches
	are the same as used for accessing watched files, which makes
	more sense and avoids odd and confusing error conditions.

	Rework storage allocation for domain names.  This fixes a security
	bug that can cause heap-overwrite with long domain names.
	CVE-2026-2291 covers this and a simple patch for existing
	releases was released with the CVE. This patch reworks the whole
	code base to make it cleaner and less liable to future
	confusions. Either upgrading to 2.93 or applying the patch
	to earlier versions is sufficient to close the security hole.
	Thanks to Andrew S. Fasano for spotting this problem in the
	first place.

---
diff --git a/0001-Make-inotify-initialization-non-fatal-error.patch b/0001-Make-inotify-initialization-non-fatal-error.patch
deleted file mode 100644
index 58b9390..0000000
--- a/0001-Make-inotify-initialization-non-fatal-error.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-From f55698272a23bdcbb993712a4f7cab3fa660207e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
-Date: Wed, 11 Feb 2026 22:02:48 +0100
-Subject: [PATCH] Make inotify initialization non-fatal error
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-When inotify watch creation is not successful, print only warning. Retry
-after dropping privileges because that might help too. Log warning only
-the second time, when logging is properly initialized.
-
-Signed-off-by: Petr Menšík <pemensik@redhat.com>
----
- src/dnsmasq.c | 13 +++++++++++--
- src/dnsmasq.h |  2 +-
- src/inotify.c | 22 ++++++++++++++++------
- 3 files changed, 28 insertions(+), 9 deletions(-)
-
-diff --git a/src/dnsmasq.c b/src/dnsmasq.c
-index 6369a14..91f4efd 100644
---- a/src/dnsmasq.c
-+++ b/src/dnsmasq.c
-@@ -441,7 +441,7 @@ int main (int argc, char **argv)
- #ifdef HAVE_INOTIFY
-   if ((daemon->port != 0 && !option_bool(OPT_NO_RESOLV)) ||
-       daemon->dynamic_dirs)
--    inotify_dnsmasq_init();
-+    inotify_dnsmasq_init(0);
-   else
-     daemon->inotifyfd = -1;
- #endif
-@@ -865,6 +865,15 @@ int main (int argc, char **argv)
-     }
- #endif
- 
-+#ifdef HAVE_INOTIFY
-+  /* inotify creation failed for the root user.
-+   * Retry with unprivileged user, log warnings this time. */
-+  if (daemon->inotifyfd == -1 &&
-+      ((daemon->port != 0 && !option_bool(OPT_NO_RESOLV)) ||
-+       daemon->dynamic_dirs))
-+    inotify_dnsmasq_init(1);
-+#endif
-+
-   if (daemon->port == 0)
-     my_syslog(LOG_INFO, _("started, version %s DNS disabled"), VERSION);
-   else 
-@@ -1296,7 +1305,7 @@ int main (int argc, char **argv)
- 	  check_ubus_listeners();
- 	}
- #endif
--      
-+
-       if (daemon->port != 0)
- 	check_dns_listeners(now);
- 
-diff --git a/src/dnsmasq.h b/src/dnsmasq.h
-index 3d176ba..6ceb697 100644
---- a/src/dnsmasq.h
-+++ b/src/dnsmasq.h
-@@ -1889,7 +1889,7 @@ int detect_loop(char *query, int type);
- 
- /* inotify.c */
- #ifdef HAVE_INOTIFY
--void inotify_dnsmasq_init(void);
-+void inotify_dnsmasq_init(int log_warn);
- int inotify_check(time_t now);
- void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revhashsz);
- #endif
-diff --git a/src/inotify.c b/src/inotify.c
-index f70daea..d01b416 100644
---- a/src/inotify.c
-+++ b/src/inotify.c
-@@ -85,18 +85,22 @@ static char *my_readlink(char *path)
-     }
- }
- 
--void inotify_dnsmasq_init()
-+void inotify_dnsmasq_init(int log_warn)
- {
-   struct resolvc *res;
-   inotify_buffer = safe_malloc(INOTIFY_SZ);
-   daemon->inotifyfd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
--  
-+
-   if (daemon->inotifyfd == -1)
--    die(_("failed to create inotify: %s"), NULL, EC_MISC);
-+    {
-+      if (log_warn)
-+        my_syslog(LOG_WARNING, _("failed to create inotify: %s"), strerror(errno));
-+      return;
-+    }
- 
-   if (daemon->port == 0 || option_bool(OPT_NO_RESOLV))
-     return;
--  
-+
-   for (res = daemon->resolv_files; res; res = res->next)
-     {
-       char *d, *new_path, *path = safe_malloc(strlen(res->name) + 1);
-@@ -127,8 +131,14 @@ void inotify_dnsmasq_init()
- 	    die(_("directory %s for resolv-file is missing, cannot poll"), res->name, EC_MISC);
- 	}	  
- 	 
--      if (res->wd == -1)
--	die(_("failed to create inotify for %s: %s"), res->name, EC_MISC);
-+      if (res->wd == -1) {
-+	free(path);
-+	if (log_warn)
-+	  my_syslog(LOG_WARNING, _("failed to create inotify watch for %s: %s"), res->name, strerror(errno));
-+	close(daemon->inotifyfd);
-+	daemon->inotifyfd = -1;
-+	return;
-+      }
- 	
-     }
- }
--- 
-2.53.0
-

diff --git a/dnsmasq-2.92-dnssec-wildcard.patch b/dnsmasq-2.92-dnssec-wildcard.patch
deleted file mode 100644
index 86ad6d9..0000000
--- a/dnsmasq-2.92-dnssec-wildcard.patch
+++ /dev/null
@@ -1,203 +0,0 @@
-From 32f10cda64b92b3559cc3b8b4479399496bddb64 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon@thekelleys.org.uk>
-Date: Mon, 12 Jan 2026 21:55:41 +0000
-Subject: [PATCH] Fix a corner-case in DNSSEC validation with wildcards.
-
-If we have a wildcard record *.example.com and recieve a query for
-a.example.com then that's OK, but we have to check that there isn't
-an actual a.example.com record. The corner case is when we get a
-query for *.example.com in that case the non-existence check
-is not required, but was being done.
-
-Thanks to Jan Breig for spotting this.
----
- src/dnsmasq.h |  7 +++----
- src/dnssec.c  | 47 +++++++++++++++++++++++------------------------
- 2 files changed, 26 insertions(+), 28 deletions(-)
-
-diff --git a/src/dnsmasq.h b/src/dnsmasq.h
-index 58be09f..934517f 100644
---- a/src/dnsmasq.h
-+++ b/src/dnsmasq.h
-@@ -760,10 +760,9 @@ struct dyndir {
- #define STAT_NEED_DS            0x40000
- #define STAT_NEED_KEY           0x50000
- #define STAT_TRUNCATED          0x60000
--#define STAT_SECURE_WILDCARD    0x70000
--#define STAT_OK                 0x80000
--#define STAT_ABANDONED          0x90000
--#define STAT_ASYNC              0xa0000
-+#define STAT_OK                 0x70000
-+#define STAT_ABANDONED          0x80000
-+#define STAT_ASYNC              0x90000
- 
- #define DNSSEC_FAIL_NYV         0x0001 /* key not yet valid */
- #define DNSSEC_FAIL_EXP         0x0002 /* key expired */
-diff --git a/src/dnssec.c b/src/dnssec.c
-index 3951620..b5e6b35 100644
---- a/src/dnssec.c
-+++ b/src/dnssec.c
-@@ -438,8 +438,6 @@ int dec_counter(int *counter, char *message)
- /* Validate a single RRset (class, type, name) in the supplied DNS reply 
-    Return code:
-    STAT_SECURE   if it validates.
--   STAT_SECURE_WILDCARD if it validates and is the result of wildcard expansion.
--   (In this case *wildcard_out points to the "body" of the wildcard within name.) 
-    STAT_BOGUS    signature is wrong, bad packet.
-    STAT_ABANDONED validation abandoned do to excess resource usage.
-    STAT_NEED_KEY need DNSKEY to complete validation (name is returned in keyname)
-@@ -455,7 +453,7 @@ int dec_counter(int *counter, char *message)
-    ttl_out is the floor on TTL, based on TTL and orig_ttl and expiration of sig used to validate.
- */
- static int validate_rrset(time_t now, struct dns_header *header, size_t plen, int class, int type, int sigidx, int rrsetidx, 
--			  char *name, char *keyname, char **wildcard_out, struct blockdata *key, int keylen,
-+			  char *name, char *keyname, int *wildcard_offset_out, struct blockdata *key, int keylen,
- 			  int algo_in, int keytag_in, unsigned long *ttl_out, int *validate_counter)
- {
-   unsigned char *p;
-@@ -468,8 +466,8 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
-   unsigned long curtime = time(0);
-   int time_check = is_check_date(curtime);
-   
--  if (wildcard_out)
--    *wildcard_out = NULL;
-+  if (wildcard_offset_out)
-+    *wildcard_offset_out = 0;
-   
-   name_labels = count_labels(name); /* For 4035 5.3.2 check */
- 
-@@ -578,7 +576,9 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
- 	  name_start = name;
- 	  
- 	  /* if more labels than in RRsig name, hash *.<no labels in rrsig labels field>  4035 5.3.2 */
--	  if (labels < name_labels)
-+	  /* If the name is already the wildcard, we're not going to change it. */
-+	  if (labels < name_labels &&
-+	      !(name_labels - labels == 1 && name_start[0] == '*' && name_start[1] == '.'))
- 	    {
- 	      for (j = name_labels - labels; j != 0; j--)
- 		{
-@@ -588,11 +588,11 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
- 		    name_start++;
- 		}
- 	      
--	      if (wildcard_out)
--		*wildcard_out = name_start+1;
--
-+	      if (wildcard_offset_out)
-+		*wildcard_offset_out = name_start - name + 1;
-+	      
- 	      name_start--;
--	      *name_start = '*';
-+	      *name_start = '*';	      
- 	    }
- 	  
- 	  wire_len = to_wire(name_start);
-@@ -691,7 +691,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
- 		  return STAT_ABANDONED;
- 		
- 		if (verify(crecp->addr.key.keydata, crecp->addr.key.keylen, sig, sig_len, digest, hash->digest_size, algo))
--		  return (labels < name_labels) ? STAT_SECURE_WILDCARD : STAT_SECURE;
-+		  return STAT_SECURE;
- 		
- 		/* An attacker can waste a lot of our CPU by setting up a giant DNSKEY RRSET full of failing
- 		   keys, all of which we have to try. Since many failing keys is not likely for
-@@ -1549,7 +1549,7 @@ static int check_nsec3_coverage(struct dns_header *header, size_t plen, int dige
- 
- /* returns 0 on success, or DNSSEC_FAIL_* value on failure. */
- static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, unsigned char **nsecs, int nsec_count, char *workspace1,
--				     char *workspace2, char *name, int type, char *wildname, int *nons, int *validate_counter)
-+				     char *workspace2, char *name, int type, int wild_offset, int *nons, int *validate_counter)
- {
-   unsigned char *salt, *p, *digest;
-   int digest_len, i, iterations, salt_len, base32_len, algo = 0;
-@@ -1647,9 +1647,9 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
-       if (*closest_encloser == '.')
- 	closest_encloser++;
- 
--      if (wildname && hostname_isequal(closest_encloser, wildname))
-+      if (wild_offset != 0 && name - closest_encloser == wild_offset)
- 	break;
--
-+      
-       if (dec_counter(validate_counter, NULL))
- 	return DNSSEC_FAIL_WORK;
-       
-@@ -1691,7 +1691,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
-     return DNSSEC_FAIL_NONSEC;
-   
-   /* Finally, check that there's no seat of wildcard synthesis */
--  if (!wildname)
-+  if (wild_offset == 0)
-     {
-       if (!(wildcard = strchr(next_closest, '.')) || wildcard == next_closest)
- 	return DNSSEC_FAIL_NONSEC;
-@@ -1714,7 +1714,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
- 
- /* returns 0 on success, or DNSSEC_FAIL_* value on failure. */
- static int prove_non_existence(struct dns_header *header, size_t plen, char *keyname, char *name, int qtype, int qclass,
--			       char *wildname, int *nons, int *nsec_ttl, int *validate_counter)
-+			      int wild_offset, int *nons, int *nsec_ttl, int *validate_counter)
- {
-   static unsigned char **nsecset = NULL, **rrsig_labels = NULL;
-   static int nsecset_sz = 0, rrsig_labels_sz = 0;
-@@ -1862,7 +1862,7 @@ static int prove_non_existence(struct dns_header *header, size_t plen, char *key
-   if (type_found == T_NSEC)
-     return prove_non_existence_nsec(header, plen, nsecset, rrsig_labels, nsecs_found, daemon->workspacename, keyname, name, qtype, nons);
-   else if (type_found == T_NSEC3)
--    return prove_non_existence_nsec3(header, plen, nsecset, nsecs_found, daemon->workspacename, keyname, name, qtype, wildname, nons, validate_counter);
-+    return prove_non_existence_nsec3(header, plen, nsecset, nsecs_found, daemon->workspacename, keyname, name, qtype, wild_offset, nons, validate_counter);
-   else
-     return DNSSEC_FAIL_NONSEC;
- }
-@@ -2187,8 +2187,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
-       else
- 	{
- 	  /* Not done, validate now */
--	  int sigcnt, rrcnt;
--	  char *wildname;
-+	  int sigcnt, rrcnt, wild_offset;
- 	  
- 	  if (!explore_rrset(header, plen, class1, type1, name, keyname, &sigcnt, &rrcnt))
- 	    return STAT_BOGUS;
-@@ -2242,7 +2241,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
- 		{
- 		  unsigned long sig_ttl;
- 		  rc = validate_rrset(now, header, plen, class1, type1, sigcnt,
--				      rrcnt, name, keyname, &wildname, NULL, 0, 0, 0, &sig_ttl, validate_counter);
-+				      rrcnt, name, keyname, &wild_offset, NULL, 0, 0, 0, &sig_ttl, validate_counter);
- 		  
- 		  if (STAT_ISEQUAL(rc, STAT_BOGUS) || STAT_ISEQUAL(rc, STAT_NEED_KEY) || STAT_ISEQUAL(rc, STAT_NEED_DS) || STAT_ISEQUAL(rc, STAT_ABANDONED))
- 		    {
-@@ -2251,7 +2250,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
- 		      return rc;
- 		    } 
- 		  
--		  /* rc is now STAT_SECURE or STAT_SECURE_WILDCARD */
-+		  /* rc is now STAT_SECURE  */
- 		  
- 		  /* Note that RR is validated */
- 		  daemon->rr_status[i] = sig_ttl;
-@@ -2277,8 +2276,8 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
- 		     Note that we may not yet have validated the NSEC/NSEC3 RRsets. 
- 		     That's not a problem since if the RRsets later fail
- 		     we'll return BOGUS then. */
--		  if (STAT_ISEQUAL(rc, STAT_SECURE_WILDCARD) &&
--		      ((rc_nsec = prove_non_existence(header, plen, keyname, name, type1, class1, wildname, NULL, NULL, validate_counter))) != 0)
-+		  if (wild_offset != 0 &&
-+		      ((rc_nsec = prove_non_existence(header, plen, keyname, name, type1, class1, wild_offset, NULL, NULL, validate_counter))) != 0)
- 		    return  (rc_nsec & DNSSEC_FAIL_WORK) ? STAT_ABANDONED : (STAT_BOGUS | rc_nsec);
- 
- 		  rc = STAT_SECURE;
-@@ -2306,7 +2305,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
- 	   the answer is in an unsigned zone, or there's NSEC records.
- 	   For a DS record, we return INSECURE, which almost always turns
- 	   into BOGUS in the caller. */
--	if ((rc_nsec = prove_non_existence(header, plen, keyname, name, qtype, qclass, NULL, nons, nsec_ttl, validate_counter)) != 0)
-+	if ((rc_nsec = prove_non_existence(header, plen, keyname, name, qtype, qclass, 0, nons, nsec_ttl, validate_counter)) != 0)
- 	  {
- 	    if (rc_nsec & DNSSEC_FAIL_WORK)
- 	      return STAT_ABANDONED;
--- 
-2.54.0
-

diff --git a/dnsmasq-2.93-CVE-2026-6507.patch b/dnsmasq-2.93-CVE-2026-6507.patch
deleted file mode 100644
index 5532255..0000000
--- a/dnsmasq-2.93-CVE-2026-6507.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 9ad74926d4f7f34ff902e1db5235535aa813c33f Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon@thekelleys.org.uk>
-Date: Mon, 6 Apr 2026 22:22:43 +0100
-Subject: [PATCH] Fix 1-byte buffer overflow in relay_reply4()
-
-Potential SIGSEGV when using DHCPv4-relay.
-
-Thanks to Asim Viladi Oglu Manizada for finding this.
----
- src/rfc2131.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/rfc2131.c b/src/rfc2131.c
-index 7bdfefd3..55aad030 100644
---- a/src/rfc2131.c
-+++ b/src/rfc2131.c
-@@ -3248,7 +3248,7 @@ unsigned int relay_reply4(struct dhcp_packet *mess, size_t sz, char *arrival_int
- 
- 	      /* delete agent info before return RFC 3046 para 2.1 */
- 	      *opt = OPTION_END;
--	      memset(opt + 1, 0, option_len(opt) + 2);
-+	      memset(opt + 1, 0, option_len(opt) + 1);
- 	    }
- 	}
-       else if (mess->giaddr.s_addr == relay->local.addr4.s_addr)
--- 
-2.53.0
-

diff --git a/dnsmasq-2.93-dnssec-rrsig-owner.patch b/dnsmasq-2.93-dnssec-rrsig-owner.patch
deleted file mode 100644
index 4d85a27..0000000
--- a/dnsmasq-2.93-dnssec-rrsig-owner.patch
+++ /dev/null
@@ -1,236 +0,0 @@
-From dd7ef68ccb3f4303ac8e58a42cc5cb6e0223cbe6 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon@thekelleys.org.uk>
-Date: Thu, 15 Jan 2026 14:30:05 +0000
-Subject: [PATCH] Fix DNSSEC failure with spurious RRSIGs.
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The presence of wrong RRSIG RRs in replies causes DNSSEC
-validation to fail even when the RRs do not require validation
-because the zone is unsigned.
-
-This patch solves the problem and tidies up the logic.
-
-Included is some fixes for hostname_issubdomain() which suffered
-some confusions about argument order :) I've clarified that and
-checked every to the function to make sure they are using the
-correct argument order.
-
-Note that, at the time of this commit, Google DNS appears to have
-the same bug, so if you're using 8.8.8.8 or friends as upstream,
-resolving the broken zones (eg rivcoed.org) will still fail.
-
-Thanks to Petr Menšík for the bug report.
----
- src/dnssec.c | 119 ++++++++++++++++++++++-----------------------------
- src/util.c   |  10 ++---
- 2 files changed, 57 insertions(+), 72 deletions(-)
-
-diff --git a/src/dnssec.c b/src/dnssec.c
-index ef67eb6..81a6fce 100644
---- a/src/dnssec.c
-+++ b/src/dnssec.c
-@@ -370,45 +370,42 @@ static int explore_rrset(struct dns_header *header, size_t plen, int class, int
- 	      
- 	      GETSHORT(type_covered, p);
- 	      p += 16; /* algo, labels, orig_ttl, sig_expiration, sig_inception, key_tag */
--	      
--	      if (gotkey)
--		{
--		  /* If there's more than one SIG, ensure they all have same keyname */
--		  if (extract_name(header, plen, &p, keyname, EXTR_NAME_COMPARE, 0) != 1)
--		    return 0;
--		}
--	      else
-+
-+	      if (type_covered == type)
- 		{
--		  gotkey = 1;
--		  
--		  if (!extract_name(header, plen, &p, keyname, EXTR_NAME_EXTRACT, 0))
-+		  if (!extract_name(header, plen, &p, daemon->workspacename, EXTR_NAME_EXTRACT, 0))
- 		    return 0;
--		  
-+
- 		  /* RFC 4035 5.3.1 says that the Signer's Name field MUST equal
- 		     the name of the zone containing the RRset. We can't tell that
- 		     for certain, but we can check that  the RRset name is equal to
- 		     or encloses the signers name, which should be enough to stop 
- 		     an attacker using signatures made with the key of an unrelated 
--		     zone he controls. Note that the root key is always allowed. */
--		  if (*keyname != 0)
-+		     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)
- 		    {
--		      char *name_start;
--		      for (name_start = name; !hostname_isequal(name_start, keyname); )
--			if ((name_start = strchr(name_start, '.')))
--			  name_start++; /* chop a label off and try again */
--			else
--			  return 0;
-+		      if (gotkey)
-+			{
-+			  /* If there's more than one valid SIG, they must all have same keyname */
-+			  if (!hostname_isequal(keyname, daemon->workspacename))
-+			    return 0;
-+			}
-+		      else
-+			{
-+			  strcpy(keyname, daemon->workspacename);
-+			  gotkey = 1;
-+			}
-+		      
-+		      if (gotkey)
-+			{
-+			  if (!expand_workspace(&sigs, &sig_sz, sigidx))
-+			    return 0; 
-+		      
-+			  sigs[sigidx++] = pdata;
-+			}
- 		    }
- 		}
--		  
--	      
--	      if (type_covered == type)
--		{
--		  if (!expand_workspace(&sigs, &sig_sz, sigidx))
--		    return 0; 
--		  
--		  sigs[sigidx++] = pdata;
--		} 
- 	      
- 	      p = pdata + 6; /* restore for ADD_RDLEN */
- 	    }
-@@ -461,11 +458,13 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
-   struct crec *crecp = NULL;
-   short *rr_desc = rrfilter_desc(type);
-   u32 sig_expiration, sig_inception;
--  int failflags = DNSSEC_FAIL_NOSIG | DNSSEC_FAIL_NYV | DNSSEC_FAIL_EXP | DNSSEC_FAIL_NOKEYSUP;
--  
--  unsigned long curtime = time(0);
-+    unsigned long curtime = time(0);
-   int time_check = is_check_date(curtime);
-+  int failflags = DNSSEC_FAIL_NOSIG;
-   
-+  if (sigidx != 0)
-+    failflags |= DNSSEC_FAIL_NYV | DNSSEC_FAIL_EXP | DNSSEC_FAIL_NOKEYSUP;
-+
-   if (wildcard_offset_out)
-     *wildcard_offset_out = 0;
-   
-@@ -2103,8 +2102,8 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
- 		       CNAME must be <subdomain>.<dname>
- 		       CNAME target must be <subdomain>.<dname_target>
- 		       <subdomain>s must match for name and target. */ 
--		    if (hostname_issubdomain(name, daemon->cname) == 1 &&
--			hostname_issubdomain(keyname, daemon->workspacename) == 1 &&
-+		    if (hostname_issubdomain(daemon->cname, name) == 1 &&
-+			hostname_issubdomain(daemon->workspacename, keyname) == 1 &&
- 			name_prefix_len == strlen(daemon->workspacename) - strlen(keyname))
- 		      {
- 			char save = daemon->cname[name_prefix_len];
-@@ -2188,41 +2187,27 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
- 	  if (!explore_rrset(header, plen, class1, type1, name, keyname, &sigcnt, &rrcnt))
- 	    return STAT_BOGUS;
- 	  
--	  /* No signatures for RRset. We can be configured to assume this is OK and return an INSECURE result. */
--	  if (sigcnt == 0)
--	    {
--	      /* NSEC and NSEC3 records must be signed. We make this assumption elsewhere. */
--	      if (type1 == T_NSEC || type1 == T_NSEC3)
--		return STAT_BOGUS | DNSSEC_FAIL_NOSIG;
--	      else if (nons && i >= ntohs(header->ancount))
--		/* If we're validating a DS reply, rather than looking for the value of AD bit,
--		   we only care that NSEC and NSEC3 RRs in the auth section are signed. 
--		   Return SECURE even if others (SOA....) are not. */
--		rc = STAT_SECURE;
--	      else
--		{
--		  /* unsigned RRsets in auth section are not BOGUS, but do make reply insecure. */
--		  if (check_unsigned && i < ntohs(header->ancount))
--		    {
--		      rc = zone_status(name, class1, keyname, now);
--		      if (STAT_ISEQUAL(rc, STAT_SECURE))
--			rc = STAT_BOGUS | DNSSEC_FAIL_NOSIG;
--		      
--		      if (class)
--			*class = class1; /* Class for NEED_DS or NEED_KEY */
--		    }
--		  else 
--		    rc = STAT_INSECURE; 
--		  
--		  if (!STAT_ISEQUAL(rc, STAT_INSECURE))
--		    return rc;
--		}
--	    }
-+	  /* NSEC and NSEC3 records must be signed. We make this assumption elsewhere. */
-+	  if (sigcnt == 0 && (type1 == T_NSEC || type1 == T_NSEC3))
-+	    return STAT_BOGUS | DNSSEC_FAIL_NOSIG;
-+	  else if (sigcnt == 0 && nons && i >= ntohs(header->ancount))
-+	    /* If we're validating a DS reply, rather than looking for the value of AD bit,
-+	       we only care that NSEC and NSEC3 RRs in the auth section are signed. 
-+	       Return SECURE even if others (SOA....) are not. */
-+	    rc = STAT_SECURE;
-+	  else if (sigcnt == 0 && (!check_unsigned || i >= ntohs(header->ancount)))
-+	    /* unsigned RRsets in auth section are not BOGUS, but do make reply insecure. */
-+	    rc = STAT_INSECURE;
- 	  else
- 	    {
--	      /* explore_rrset() gives us key name from sigs in keyname.
-+	      /* explore_rrset() gives us zone name from sigs in keyname, if
-+		 it didn't find a key, use the name we're validating.
- 		 Can't overwrite name here. */
--	      strcpy(daemon->workspacename, keyname);
-+	      if (sigcnt == 0)
-+		strcpy(daemon->workspacename, name);
-+	      else
-+		strcpy(daemon->workspacename, keyname);
-+	      
- 	      rc = zone_status(daemon->workspacename, class1, keyname, now);
- 	      
- 	      if (STAT_ISEQUAL(rc, STAT_BOGUS) || STAT_ISEQUAL(rc, STAT_NEED_KEY) || STAT_ISEQUAL(rc, STAT_NEED_DS))
-@@ -2232,7 +2217,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
- 		  return rc;
- 		}
- 	      
--	      /* Zone is insecure, don't need to validate RRset */
-+	      /* If zone is insecure, don't need to validate RRset, and rc remains as STAT_INSECURE*/
- 	      if (STAT_ISEQUAL(rc, STAT_SECURE))
- 		{
- 		  unsigned long sig_ttl;
-diff --git a/src/util.c b/src/util.c
-index 21dbb66..e4d74e6 100644
---- a/src/util.c
-+++ b/src/util.c
-@@ -443,8 +443,8 @@ int hostname_issubdomain(char *a, char *b)
-   for (ap = a; *ap; ap++); 
-   for (bp = b; *bp; bp++);
- 
--  /* a shorter than b or a empty. */
--  if ((bp - b) < (ap - a) || ap == a)
-+  /* a shorter than b */
-+  if ((ap - a) < (bp - b))
-     return 0;
- 
-   do
-@@ -459,12 +459,12 @@ int hostname_issubdomain(char *a, char *b)
- 
-        if (c1 != c2)
- 	 return 0;
--    } while (ap != a);
-+    } while (bp != b);
- 
--  if (bp == b)
-+  if (ap == a)
-     return 2;
- 
--  if (*(--bp) == '.')
-+  if (*(--ap) == '.')
-     return 1;
- 
-   return 0;
--- 
-2.52.0
-

diff --git a/dnsmasq.spec b/dnsmasq.spec
index 8a3f0dc..a117bb9 100644
--- a/dnsmasq.spec
+++ b/dnsmasq.spec
@@ -20,6 +20,8 @@
 # But upstream gitweb seems to block direct links like this, they are not usable anymore.
 %define up_patch_url() https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=patch;h=%{1}
 %global upstream_sources 0 3
+%global pgp_signature_sources 3
+%global pgp_keyring_sources 4
 
 
 # Attempt to prepare source-git with downstream repos
@@ -33,8 +35,8 @@
 %endif
 
 Name:           dnsmasq
-Version:        2.92rel2
-Release:        9%{?extraversion:.%{extraversion}}%{?extrabuild:.%{extrabuild}}%{?dist}
+Version:        2.93
+Release:        1%{?extraversion:.%{extraversion}}%{?extrabuild:.%{extrabuild}}%{?dist}
 Summary:        A lightweight DHCP/caching DNS server
 
 # SPDX identifiers already
@@ -59,14 +61,6 @@ Patch1:         dnsmasq-2.77-underflow.patch
 Patch2:         dnsmasq-2.81-configuration.patch
 Patch3:         dnsmasq-2.78-fips.patch
 Patch7:         dnsmasq-2.90-dbus-interfaces.patch
-# https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2026q1/018378.html
-Patch8:         %{up_patch_url f603a4f920e6953b11667d424956fd47373870e9}#/dnsmasq-2.92-dnssec-wildcard.patch
-# https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2026q1/018383.html
-Patch9:         %{up_patch_url 1269f074f86bb959863012063060a3a082d37dc4}#/dnsmasq-2.93-dnssec-rrsig-owner.patch
-# https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2026q1/018409.html
-Patch10:        0001-Make-inotify-initialization-non-fatal-error.patch
-# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=9ad74926d4f7f34ff902e1db5235535aa813c33f
-Patch11:        %{up_patch_url 9ad74926d4f7f34ff902e1db5235535aa813c33f}#/dnsmasq-2.93-CVE-2026-6507.patch
 
 
 Requires:       nettle
@@ -263,6 +257,9 @@ fi
 %endif
 
 %changelog
+* Thu Jul 02 2026 Petr Menšík <pemensik@redhat.com> - 2.93-1
+- Update to 2.93 (rbhz#2484748)
+
 * Tue May 12 2026 Petr Menšík <pemensik@redhat.com> - 2.92rel2-9
 - Update to 2.92rel2 (rhbz#2469245)
 

diff --git a/sources b/sources
index 97105bd..6a15cf6 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
-SHA512 (dnsmasq-2.92rel2.tar.xz) = 607abf33d6eac24eafdff9cd291d84b065354303d5e1d9514d79085b247fb3861ac57851ca1dfc4a5cddd314f8b970d17e93b987b1576e9f6ba1d6bffd42fff1
-SHA512 (dnsmasq-2.92rel2.tar.xz.asc) = 140161d89287ab46fe15f7b68264a166e1a1f1a019cc781b0013a6345790e3f75186a023b32e526e7b5c05584734dfaff7e3b76b3c01878c0d22d9f6a039fcde
+SHA512 (dnsmasq-2.93.tar.xz) = ee442c634c54f103e034ee5259f1802895f9e9d172891f14c644e260519da73f5dd6f28b75cb84c0b1cc5f9ec464ba8f40c87095fa96719cb0df831eae0887ee
+SHA512 (dnsmasq-2.93.tar.xz.asc) = 13b34102d8593fab8c859ca839ec240478e2382c35251afb3d69b73124a4826031d8945fe33c92f9b5302e49b1789f3db5c0d7ae98118aeba4ee317767c46dd9

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-07-03 16:54 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-03 16:54 [rpms/dnsmasq] rawhide: Update to 2.93 (rbhz#2484748) 

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox