diff --git a/SOURCES/dnsmasq-2.79-cname-collision.patch b/SOURCES/dnsmasq-2.79-cname-collision.patch new file mode 100644 index 0000000..4dcce03 --- /dev/null +++ b/SOURCES/dnsmasq-2.79-cname-collision.patch @@ -0,0 +1,432 @@ +commit 244dba98c6d93c84a362177bb4ef629b6b3345d0 +Author: Tomas Korbar +Date: Tue Aug 19 11:03:38 2025 +0200 + + Backport of upstream commits + + 45d8a2435e8200e892b82b6a04c7ddfb07a4165a + eb1fe15ca80b6bc43cd6bfdf309ec6c590aff811 + +diff --git a/src/cache.c b/src/cache.c +index 8b1b560..612ad22 100644 +--- a/src/cache.c ++++ b/src/cache.c +@@ -77,17 +77,20 @@ static void cache_link(struct crec *crecp); + static void rehash(int size); + static void cache_hash(struct crec *crecp); + +-static unsigned int next_uid(void) ++void next_uid(struct crec *crecp) + { + static unsigned int uid = 0; + +- uid++; +- +- /* uid == 0 used to indicate CNAME to interface name. */ +- if (uid == SRC_INTERFACE) +- uid++; ++ if (crecp->uid == UID_NONE) ++ { ++ uid++; + +- return uid; ++ /* uid == 0 used to indicate CNAME to interface name. */ ++ if (uid == UID_NONE) ++ uid++; ++ ++ crecp->uid = uid; ++ } + } + + void cache_init(void) +@@ -105,7 +108,7 @@ void cache_init(void) + { + cache_link(crecp); + crecp->flags = 0; +- crecp->uid = next_uid(); ++ crecp->uid = UID_NONE; + } + } + +@@ -204,7 +207,7 @@ static void cache_free(struct crec *crecp) + { + crecp->flags &= ~F_FORWARD; + crecp->flags &= ~F_REVERSE; +- crecp->uid = next_uid(); /* invalidate CNAMES pointing to this. */ ++ crecp->uid = UID_NONE; /* invalidate CNAMES pointing to this. */ + + if (cache_tail) + cache_tail->next = crecp; +@@ -322,7 +325,8 @@ static int is_expired(time_t now, struct crec *crecp) + return 1; + } + +-static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags) ++static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags, ++ struct crec **target_crec, unsigned int *target_uid) + { + /* Scan and remove old entries. + If (flags & F_FORWARD) then remove any forward entries for name and any expired +@@ -335,7 +339,10 @@ static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t no + to a cache entry if the name exists in the cache as a HOSTS or DHCP entry (these are never deleted) + + We take advantage of the fact that hash chains have stuff in the order ,, +- so that when we hit an entry which isn't reverse and is immortal, we're done. */ ++ so that when we hit an entry which isn't reverse and is immortal, we're done. ++ ++ If we free a crec which is a CNAME target, return the entry and uid in target_crec and target_uid. ++ This entry will get re-used with the same name, to preserve CNAMEs. */ + + struct crec *crecp, **up; + +@@ -343,17 +350,6 @@ static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t no + { + for (up = hash_bucket(name), crecp = *up; crecp; crecp = crecp->hash_next) + { +- if (is_expired(now, crecp) || is_outdated_cname_pointer(crecp)) +- { +- *up = crecp->hash_next; +- if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))) +- { +- cache_unlink(crecp); +- cache_free(crecp); +- } +- continue; +- } +- + if ((crecp->flags & F_FORWARD) && hostname_isequal(cache_get_name(crecp), name)) + { + /* Don't delete DNSSEC in favour of a CNAME, they can co-exist */ +@@ -363,6 +359,16 @@ static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t no + if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) + return crecp; + *up = crecp->hash_next; ++ /* If this record is for the name we're inserting and is the target ++ of a CNAME record. Make the new record for the same name, in the same ++ crec, with the same uid to avoid breaking the existing CNAME. */ ++ if (crecp->uid != UID_NONE) ++ { ++ if (target_crec) ++ *target_crec = crecp; ++ if (target_uid) ++ *target_uid = crecp->uid; ++ } + cache_unlink(crecp); + cache_free(crecp); + continue; +@@ -381,6 +387,18 @@ static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t no + } + #endif + } ++ ++ if (is_expired(now, crecp) || is_outdated_cname_pointer(crecp)) ++ { ++ *up = crecp->hash_next; ++ if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))) ++ { ++ cache_unlink(crecp); ++ cache_free(crecp); ++ } ++ continue; ++ } ++ + up = &crecp->hash_next; + } + } +@@ -447,11 +465,12 @@ void cache_start_insert(void) + struct crec *cache_insert(char *name, struct all_addr *addr, + time_t now, unsigned long ttl, unsigned short flags) + { +- struct crec *new; ++ struct crec *new, *target_crec = NULL; + union bigname *big_name = NULL; + int freed_all = flags & F_REVERSE; + int free_avail = 0; +- ++ unsigned int target_uid; ++ + /* Don't log DNSSEC records here, done elsewhere */ + if (flags & (F_IPV4 | F_IPV6 | F_CNAME)) + { +@@ -469,7 +488,7 @@ struct crec *cache_insert(char *name, struct all_addr *addr, + + /* First remove any expired entries and entries for the name/address we + are currently inserting. */ +- if ((new = cache_scan_free(name, addr, now, flags))) ++ if ((new = cache_scan_free(name, addr, now, flags, &target_crec, &target_uid))) + { + /* We're trying to insert a record over one from + /etc/hosts or DHCP, or other config. If the +@@ -493,81 +512,89 @@ struct crec *cache_insert(char *name, struct all_addr *addr, + } + + /* Now get a cache entry from the end of the LRU list */ +- while (1) { +- if (!(new = cache_tail)) /* no entries left - cache is too small, bail */ +- { +- insert_error = 1; +- return NULL; +- } +- +- /* End of LRU list is still in use: if we didn't scan all the hash +- chains for expired entries do that now. If we already tried that +- then it's time to start spilling things. */ +- +- if (new->flags & (F_FORWARD | F_REVERSE)) +- { +- /* If free_avail set, we believe that an entry has been freed. +- Bugs have been known to make this not true, resulting in +- a tight loop here. If that happens, abandon the +- insert. Once in this state, all inserts will probably fail. */ +- if (free_avail) +- { +- static int warned = 0; +- if (!warned) +- { +- my_syslog(LOG_ERR, _("Internal error in cache.")); +- warned = 1; +- } +- insert_error = 1; +- return NULL; +- } +- +- if (freed_all) +- { +- struct all_addr free_addr = new->addr.addr;; ++ if (!target_crec) ++ while (1) { ++ if (!(new = cache_tail)) /* no entries left - cache is too small, bail */ ++ { ++ insert_error = 1; ++ return NULL; ++ } ++ ++ /* Free entry at end of LRU list, use it. */ ++ if (!(new->flags & (F_FORWARD | F_REVERSE))) ++ break; + ++ /* End of LRU list is still in use: if we didn't scan all the hash ++ chains for expired entries do that now. If we already tried that ++ then it's time to start spilling things. */ ++ ++ /* If free_avail set, we believe that an entry has been freed. ++ Bugs have been known to make this not true, resulting in ++ a tight loop here. If that happens, abandon the ++ insert. Once in this state, all inserts will probably fail. */ ++ if (free_avail) ++ { ++ static int warned = 0; ++ if (!warned) ++ { ++ my_syslog(LOG_ERR, _("Internal error in cache.")); ++ warned = 1; ++ } ++ insert_error = 1; ++ return NULL; ++ } ++ ++ if (freed_all) ++ { ++ struct all_addr free_addr = new->addr.addr;; ++ + #ifdef HAVE_DNSSEC +- /* For DNSSEC records, addr holds class. */ +- if (new->flags & (F_DS | F_DNSKEY)) +- free_addr.addr.dnssec.class = new->uid; ++ /* For DNSSEC records, addr holds class. */ ++ if (new->flags & (F_DS | F_DNSKEY)) ++ free_addr.addr.dnssec.class = new->uid; + #endif +- +- free_avail = 1; /* Must be free space now. */ +- cache_scan_free(cache_get_name(new), &free_addr, now, new->flags); +- cache_live_freed++; +- } +- else +- { +- cache_scan_free(NULL, NULL, now, 0); +- freed_all = 1; +- } +- continue; +- } +- +- /* Check if we need to and can allocate extra memory for a long name. +- If that fails, give up now, always succeed for DNSSEC records. */ +- if (name && (strlen(name) > SMALLDNAME-1)) +- { +- if (big_free) +- { +- big_name = big_free; +- big_free = big_free->next; +- } +- else if ((bignames_left == 0 && !(flags & (F_DS | F_DNSKEY))) || +- !(big_name = (union bigname *)whine_malloc(sizeof(union bigname)))) +- { +- insert_error = 1; +- return NULL; +- } +- else if (bignames_left != 0) +- bignames_left--; +- +- } ++ ++ free_avail = 1; /* Must be free space now. */ ++ cache_scan_free(cache_get_name(new), &free_addr, now, new->flags, NULL, NULL); ++ cache_live_freed++; ++ } ++ else ++ { ++ cache_scan_free(NULL, NULL, now, 0, NULL, NULL); ++ freed_all = 1; ++ } ++ } ++ ++ /* Check if we need to and can allocate extra memory for a long name. ++ If that fails, give up now, always succeed for DNSSEC records. */ ++ if (name && (strlen(name) > SMALLDNAME-1)) ++ { ++ if (big_free) ++ { ++ big_name = big_free; ++ big_free = big_free->next; ++ } ++ else if ((bignames_left == 0 && !(flags & (F_DS | F_DNSKEY))) || ++ !(big_name = (union bigname *)whine_malloc(sizeof(union bigname)))) ++ { ++ insert_error = 1; ++ return NULL; ++ } ++ else if (bignames_left != 0) ++ bignames_left--; ++ ++ } + +- /* Got the rest: finally grab entry. */ +- cache_unlink(new); +- break; +- } ++ /* If we freed a cache entry for our name which was a CNAME target, use that. ++ and preserve the uid, so that existing CNAMES are not broken. */ ++ if (target_crec) ++ { ++ new = target_crec; ++ new->uid = target_uid; ++ } ++ ++ /* Got the rest: finally grab entry. */ ++ cache_unlink(new); + + new->flags = flags; + if (big_name) +@@ -787,8 +814,9 @@ static void add_hosts_cname(struct crec *target) + crec->ttd = a->ttl; + crec->name.namep = a->alias; + crec->addr.cname.target.cache = target; ++ next_uid(target); + crec->addr.cname.uid = target->uid; +- crec->uid = next_uid(); ++ crec->uid = UID_NONE; + cache_hash(crec); + add_hosts_cname(crec); /* handle chains */ + } +@@ -1071,7 +1099,7 @@ void cache_reload(void) + cache->name.namep = a->alias; + cache->addr.cname.target.int_name = intr; + cache->addr.cname.uid = SRC_INTERFACE; +- cache->uid = next_uid(); ++ cache->uid = UID_NONE; + cache_hash(cache); + add_hosts_cname(cache); /* handle chains */ + } +@@ -1201,8 +1229,9 @@ static void add_dhcp_cname(struct crec *target, time_t ttd) + aliasc->ttd = ttd; + aliasc->name.namep = a->alias; + aliasc->addr.cname.target.cache = target; ++ next_uid(target); + aliasc->addr.cname.uid = target->uid; +- aliasc->uid = next_uid(); ++ aliasc->uid = UID_NONE; + cache_hash(aliasc); + add_dhcp_cname(aliasc, ttd); + } +@@ -1243,7 +1272,7 @@ void cache_add_dhcp_entry(char *host_name, int prot, + } + else if (!(crec->flags & F_DHCP)) + { +- cache_scan_free(host_name, NULL, 0, crec->flags & (flags | F_CNAME | F_FORWARD)); ++ cache_scan_free(host_name, NULL, 0, crec->flags & (flags | F_CNAME | F_FORWARD), NULL, NULL); + /* scan_free deletes all addresses associated with name */ + break; + } +@@ -1270,7 +1299,7 @@ void cache_add_dhcp_entry(char *host_name, int prot, + if (crec->flags & F_NEG) + { + flags |= F_REVERSE; +- cache_scan_free(NULL, (struct all_addr *)host_address, 0, flags); ++ cache_scan_free(NULL, (struct all_addr *)host_address, 0, flags, NULL, NULL); + } + } + else +@@ -1290,7 +1319,7 @@ void cache_add_dhcp_entry(char *host_name, int prot, + crec->ttd = ttd; + crec->addr.addr = *host_address; + crec->name.namep = host_name; +- crec->uid = next_uid(); ++ crec->uid = UID_NONE; + cache_hash(crec); + + add_dhcp_cname(crec, ttd); +diff --git a/src/dnsmasq.h b/src/dnsmasq.h +index cf1c9c4..2d83a48 100644 +--- a/src/dnsmasq.h ++++ b/src/dnsmasq.h +@@ -471,8 +471,12 @@ struct crec { + #define F_NOEXTRA (1u<<27) + #define F_SERVFAIL (1u<<28) + ++#define UID_NONE 0 + /* Values of uid in crecs with F_CONFIG bit set. */ +-#define SRC_INTERFACE 0 ++/* cname to uid SRC_INTERFACE are to interface names, ++ so use UID_NONE for that to eliminate clashes with ++ any other uid */ ++#define SRC_INTERFACE UID_NONE + #define SRC_CONFIG 1 + #define SRC_HOSTS 2 + #define SRC_AH 3 +@@ -1147,6 +1151,7 @@ extern struct daemon { + + /* cache.c */ + void cache_init(void); ++void next_uid(struct crec *crecp); + void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg); + char *record_source(unsigned int index); + char *querystr(char *desc, unsigned short type); +diff --git a/src/rfc1035.c b/src/rfc1035.c +index 48804b8..021661e 100644 +--- a/src/rfc1035.c ++++ b/src/rfc1035.c +@@ -739,6 +739,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t + newc->addr.cname.uid = 1; + if (cpp) + { ++ next_uid(newc); + cpp->addr.cname.target.cache = newc; + cpp->addr.cname.uid = newc->uid; + } +@@ -795,6 +796,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t + newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD | secflag); + if (newc && cpp) + { ++ next_uid(newc); + cpp->addr.cname.target.cache = newc; + cpp->addr.cname.uid = newc->uid; + } +@@ -821,6 +823,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t + newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0)); + if (newc && cpp) + { ++ next_uid(newc); + cpp->addr.cname.target.cache = newc; + cpp->addr.cname.uid = newc->uid; + } diff --git a/SOURCES/dnsmasq-2.85-forward-retries.patch b/SOURCES/dnsmasq-2.85-forward-retries.patch new file mode 100644 index 0000000..61515ad --- /dev/null +++ b/SOURCES/dnsmasq-2.85-forward-retries.patch @@ -0,0 +1,207 @@ +From b133ed74c5eb836f2a5add1f4de1c662b67f841a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= +Date: Mon, 11 Aug 2025 17:29:52 +0200 +Subject: [PATCH] Fix problem with DNS retries in 2.83/2.84. + +Combination of upstream commits: +- 141a26f979b4bc959d8e866a295e24f8cf456920 +- 305cb79c5754d5554729b18a2c06fe7ce699687a + +And following commit + +Subtly change behaviour on repeated DNS query. + +This changes the behaviour introduced in +141a26f979b4bc959d8e866a295e24f8cf456920 + +We re-introduce the distinction between a query +which is retried from the same source, and one which is +repeated from different sources. + +In the later case, we still forward the query, to avoid +problems when the reply to the first query is lost +(see f8cf456920) but we suppress the behaviour +that's used on a retry, when the query is sent to +all available servers in parallel. + +Retry -> all servers. +Repeat -> next server. + +This avoids a significant increase in upstream traffic on +busy instances which see lots of queries for common names. + +It does mean the clients which repeat queries from new source ports, +rather than retrying them from the same source port, will see +different behaviour, but it in fact restores the pre-2.83 behaviour, +so it's not expected to be a practical problem. + +(cherry picked from commit ea6b0b2665ed95baa41fe813547103f7f1ccb953) +--- + src/forward.c | 114 ++++++++++++++++++++++---------------------------- + 1 file changed, 51 insertions(+), 63 deletions(-) + +diff --git a/src/forward.c b/src/forward.c +index 64124b1..d27f230 100644 +--- a/src/forward.c ++++ b/src/forward.c +@@ -17,9 +17,6 @@ + #include "dnsmasq.h" + + static struct frec *lookup_frec(unsigned short id, int fd, void *hash); +-static struct frec *lookup_frec_by_sender(unsigned short id, +- union mysockaddr *addr, +- void *hash); + static struct frec *lookup_frec_by_query(void *hash, unsigned int flags); + + static unsigned short get_id(void); +@@ -257,6 +254,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, + #endif + unsigned int gotname = extract_request(header, plen, daemon->namebuff, NULL); + unsigned char *oph = find_pseudoheader(header, plen, NULL, NULL, NULL, NULL); ++ int old_src = 0; + + (void)do_bit; + +@@ -270,9 +268,53 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, + if (do_bit) + fwd_flags |= FREC_DO_QUESTION; + #endif +- +- /* may be no servers available. */ +- if (forward || (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, hash))) ++ ++ /* Check for retry on existing query from same source */ ++ if (forward) ++ old_src = 1; ++ else if ((forward = lookup_frec_by_query(hash, fwd_flags))) ++ { ++ struct frec_src *src; ++ ++ for (src = &forward->frec_src; src; src = src->next) ++ if (src->orig_id == ntohs(header->id) && ++ sockaddr_isequal(&src->source, udpaddr)) ++ break; ++ ++ if (src) ++ old_src = 1; ++ else ++ { ++ /* Existing query, but from new source, just add this ++ client to the list that will get the reply.*/ ++ ++ /* Note whine_malloc() zeros memory. */ ++ if (!daemon->free_frec_src && ++ daemon->frec_src_count < daemon->ftabsize && ++ (daemon->free_frec_src = whine_malloc(sizeof(struct frec_src)))) ++ { ++ daemon->frec_src_count++; ++ daemon->free_frec_src->next = NULL; ++ } ++ ++ /* If we've been spammed with many duplicates, just drop the query. */ ++ if (daemon->free_frec_src) ++ { ++ src = daemon->free_frec_src; ++ daemon->free_frec_src = src->next; ++ src->next = forward->frec_src.next; ++ forward->frec_src.next = src; ++ src->orig_id = ntohs(header->id); ++ src->source = *udpaddr; ++ src->dest = *dst_addr; ++ src->log_id = daemon->log_id; ++ src->iface = dst_iface; ++ src->fd = udpfd; ++ } ++ } ++ } ++ ++ if (forward) + { + /* If we didn't get an answer advertising a maximal packet in EDNS, + fall back to 1280, which should work everywhere on IPv6. +@@ -317,10 +359,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, + } + #endif + +- /* retry on existing query, send to all available servers */ ++ /* retry on existing query, from original source. Send to all available servers */ + domain = forward->sentto->domain; + forward->sentto->failed_queries++; +- if (!option_bool(OPT_ORDER)) ++ if (!option_bool(OPT_ORDER) && old_src) + { + sd = forward->sentto->serv_domain; + forward->forwardall = 1; +@@ -338,42 +380,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, + } + else + { +- /* Query from new source, but the same query may be in progress +- from another source. If so, just add this client to the +- list that will get the reply. +- +- Note that is the EDNS client subnet option is in use, we can't do this, +- as the clients (and therefore query EDNS options) will be different +- for each query. The EDNS subnet code has checks to avoid +- attacks in this case. */ +- if (!option_bool(OPT_CLIENT_SUBNET) && (forward = lookup_frec_by_query(hash, fwd_flags))) +- { +- /* Note whine_malloc() zeros memory. */ +- if (!daemon->free_frec_src && +- daemon->frec_src_count < daemon->ftabsize && +- (daemon->free_frec_src = whine_malloc(sizeof(struct frec_src)))) +- { +- daemon->frec_src_count++; +- daemon->free_frec_src->next = NULL; +- } +- +- /* If we've been spammed with many duplicates, just drop the query. */ +- if (daemon->free_frec_src) +- { +- struct frec_src *new = daemon->free_frec_src; +- daemon->free_frec_src = new->next; +- new->next = forward->frec_src.next; +- forward->frec_src.next = new; +- new->orig_id = ntohs(header->id); +- new->source = *udpaddr; +- new->dest = *dst_addr; +- new->log_id = daemon->log_id; +- new->iface = dst_iface; +- new->fd = udpfd; +- } +- +- return 1; +- } ++ /* new query */ + + if (gotname) + flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind, &sd); +@@ -2424,25 +2431,6 @@ static struct frec *lookup_frec(unsigned short id, int fd, void *hash) + return NULL; + } + +-static struct frec *lookup_frec_by_sender(unsigned short id, +- union mysockaddr *addr, +- void *hash) +-{ +- struct frec *f; +- struct frec_src *src; +- +- for (f = daemon->frec_list; f; f = f->next) +- if (f->sentto && +- !(f->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) && +- memcmp(hash, f->hash, HASH_SIZE) == 0) +- for (src = &f->frec_src; src; src = src->next) +- if (src->orig_id == id && +- sockaddr_isequal(&src->source, addr)) +- return f; +- +- return NULL; +-} +- + static struct frec *lookup_frec_by_query(void *hash, unsigned int flags) + { + struct frec *f; +-- +2.50.1 + diff --git a/SPECS/dnsmasq.spec b/SPECS/dnsmasq.spec index 080b437..edc61f7 100644 --- a/SPECS/dnsmasq.spec +++ b/SPECS/dnsmasq.spec @@ -13,7 +13,7 @@ Name: dnsmasq Version: 2.79 -Release: 33%{?extraversion:.%{extraversion}}%{?dist} +Release: 35%{?extraversion:.%{extraversion}}%{?dist} Summary: A lightweight DHCP/caching DNS server License: GPLv2 or GPLv3 @@ -100,6 +100,13 @@ Patch44: dnsmasq-2.85-domain-blocklist-speedup.patch Patch45: dnsmasq-2.80-synth-domain-RHEL-15216.patch # https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=214a046f47b9f7dd56f5eef3a8678ccbd6e973b7 Patch46: dnsmasq-2.90-CVE-2023-50387-CVE-2023-50868.patch +# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=141a26f979b4bc959d8e866a295e24f8cf456920 +# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=305cb79c5754d5554729b18a2c06fe7ce699687a +# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=ea6b0b2665ed95baa41fe813547103f7f1ccb953 +Patch47: dnsmasq-2.85-forward-retries.patch +# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=45d8a2435e8200e892b82b6a04c7ddfb07a4165a +# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=eb1fe15ca80b6bc43cd6bfdf309ec6c590aff811 +Patch48: dnsmasq-2.79-cname-collision.patch # This is workaround to nettle bug #1549190 # https://bugzilla.redhat.com/show_bug.cgi?id=1549190 @@ -179,6 +186,8 @@ server's leases. %patch44 -p1 -b .rh2209031 %patch45 -p1 -b .RHEL-15216 %patch46 -p1 -b .CVE-2023-50387-CVE-2023-50868 +%patch47 -p1 -b .RHEL-6586 +%patch48 -p1 -b .RHEL-61943 # use /var/lib/dnsmasq instead of /var/lib/misc for file in dnsmasq.conf.example man/dnsmasq.8 man/es/dnsmasq.8 src/config.h; do @@ -278,6 +287,13 @@ install -Dpm 644 %{SOURCE2} %{buildroot}%{_sysusersdir}/dnsmasq.conf %{_mandir}/man1/dhcp_* %changelog +* Mon Aug 18 2025 Tomas Korbar - 2.79-35 +- Fix dnsmasq caching of intertwined CNAMES +- Resolves: RHEL-61943 + +* Mon Aug 11 2025 Petr Menšík - 2.79-34 +- Enable retries again (RHEL-6586) + * Mon Mar 18 2024 Tomas Korbar - 2.79-33 - Fix CVE 2023-50387 and CVE 2023-50868 - Resolves: RHEL-25667