diff --git a/bugfix-allow-binding-mac-with-ipv6.patch b/allow-binding-mac-with-ip6.patch similarity index 36% rename from bugfix-allow-binding-mac-with-ipv6.patch rename to allow-binding-mac-with-ip6.patch index b9486d7ccfdf8b821556ea684585ce9afca7560c..4bd2022a8310788e69b6c5ddc005535c6211c21e 100644 --- a/bugfix-allow-binding-mac-with-ipv6.patch +++ b/allow-binding-mac-with-ip6.patch @@ -1,15 +1,29 @@ -From 53e1a09a06e11317bbde0e236837e5daa8d40593 Mon Sep 17 00:00:00 2001 -From: liaichun -Date: Mon, 20 Apr 2020 16:06:51 +0800 +From 271510e5f7c2130ad4b7e33186e47daf0d3d2d30 Mon Sep 17 00:00:00 2001 +From: huyizhen +Date: Fri, 28 Feb 2025 14:38:44 +0800 +Subject: [PATCH] allow binding mac with ip6 + +Bind the IPv6 address to the MAC address of the client. +This command is used to solve the problem that the client cannot obtain an IPv6 address +after the system is reinstalled. If this parameter is not specified, the client duid changes +and cannot obtain the original IPv6 address. After this parameter is added, even if the DUID +of the client changes, the client can still obtain the bound IPv6 address. +Description: +This feature conflicts with the RFC 3315 standard and applies only to private networks. +In addition, all client MAC addresses and IPv6 addresses must be bound in one-to-one mode +using --dhcp-host. +Combine bugfix-allow-binding-mac-with-ipv6.patch +bugfix-deal-with-CONFRIM-when-binding-mac-with-ipv6.patch +to allow-binding-mac-with-ip6.patch --- src/dnsmasq.c | 1 + src/dnsmasq.h | 4 +++- src/option.c | 3 +++ - src/rfc3315.c | 35 ++++++++++++++++++++++++++++++++++- - 4 files changed, 41 insertions(+), 2 deletions(-) + src/rfc3315.c | 61 ++++++++++++++++++++++++++++++++++++++++++--------- + 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/dnsmasq.c b/src/dnsmasq.c -index 5d64ceb..04c3be2 100644 +index f3d87cd..3609106 100644 --- a/src/dnsmasq.c +++ b/src/dnsmasq.c @@ -281,6 +281,7 @@ int main (int argc, char **argv) @@ -43,7 +57,7 @@ index e455c3f..ef32f06 100644 struct dhcp_netid_list *force_broadcast, *bootp_dynamic; struct hostsfile *dhcp_hosts_file, *dhcp_opts_file; diff --git a/src/option.c b/src/option.c -index f4ff7c0..c36bf63 100644 +index 9b5066e..7c316b9 100644 --- a/src/option.c +++ b/src/option.c @@ -192,6 +192,7 @@ struct myoption { @@ -71,42 +85,120 @@ index f4ff7c0..c36bf63 100644 }; diff --git a/src/rfc3315.c b/src/rfc3315.c -index 400d939..004ebb8 100644 +index 400d939..e579494 100644 --- a/src/rfc3315.c +++ b/src/rfc3315.c -@@ -49,6 +49,7 @@ static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz); +@@ -48,8 +48,8 @@ static int build_ia(struct state *state, int *t1cntr); + static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz); static void mark_context_used(struct state *state, struct in6_addr *addr); static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr); - static int check_address(struct state *state, struct in6_addr *addr); -+static int check_and_try_preempte_address(struct state *state, struct in6_addr *addr, time_t now, struct dhcp_config *config); - static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now); +-static int check_address(struct state *state, struct in6_addr *addr); +-static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now); ++static int check_address(struct dhcp_config *config, struct state *state, struct in6_addr *addr, time_t now, int preempte); ++static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now, int preempte); static struct addrlist *config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr); static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, void *ia_option, -@@ -723,7 +724,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu + unsigned int *min_time, struct in6_addr *addr, time_t now); +@@ -699,7 +699,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu + /* If the client asks for an address on the same network as a configured address, + offer the configured address instead, to make moving to newly-configured + addresses automatic. */ +- if (!(c->flags & CONTEXT_CONF_USED) && config_valid(config, c, &addr, state, now)) ++ if (!(c->flags & CONTEXT_CONF_USED) && config_valid(config, c, &addr, state, now, 0)) + { + req_addr = addr; + mark_config_used(c, &addr); +@@ -708,7 +708,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu + } + else if (!(c = address6_available(state->context, &req_addr, solicit_tags, plain_range))) + continue; /* not an address we're allowed */ +- else if (!check_address(state, &req_addr)) ++ else if (!check_address(config, state, &req_addr, now, 0)) + continue; /* address leased elsewhere */ + + /* add address to output packet */ +@@ -723,7 +723,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu for (c = state->context; c; c = c->current) if (!(c->flags & CONTEXT_CONF_USED) && match_netid(c->filter, solicit_tags, plain_range) && - config_valid(config, c, &addr, state, now)) -+ config_valid(config, c, &addr, state, now) && -+ check_and_try_preempte_address(state, &addr, now, config)) ++ config_valid(config, c, &addr, state, now, 1)) { mark_config_used(state->context, &addr); if (have_config(config, CONFIG_TIME)) -@@ -1313,6 +1315,37 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu - - } +@@ -879,7 +879,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu + put_opt6_string(_("address unavailable")); + end_opt6(o1); + } +- else if (!check_address(state, &req_addr)) ++ else if (!check_address(config, state, &req_addr, now, 0)) + { + /* Address leased to another DUID/IAID */ + o1 = new_opt6(OPTION6_STATUS_CODE); +@@ -1075,12 +1075,32 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu + case DHCP6CONFIRM: + { + int good_addr = 0, bad_addr = 0; ++ int find_bind = 0; ++ struct dhcp_config *find_config = NULL; -+static int check_and_try_preempte_address(struct state *state, struct in6_addr *addr, time_t now, struct dhcp_config *config) -+{ -+ struct dhcp_lease *lease; + /* set reply message type */ + outmsgtype = DHCP6REPLY; + + log6_quiet(state, "DHCPCONFIRM", NULL, NULL); +- + -+ if (!(lease = lease6_find_by_addr(addr, 128, 0))) -+ { -+ return 1; -+ } ++ if(daemon->bind_mac_with_ip6) { ++ if(state->mac) { ++ for (find_config = daemon->dhcp_conf; find_config; find_config = find_config->next) ++ if (config_has_mac(find_config, state->mac, state->mac_len, state->mac_type) && have_config(find_config, CONFIG_ADDR6)) { ++ find_bind = 1; ++ break; ++ } ++ } ++ /* requires all mac has binding ipv6 address. */ ++ if (find_bind == 0) { ++ o1 = new_opt6(OPTION6_STATUS_CODE); ++ put_opt6_short(DHCP6NOTONLINK); ++ put_opt6_string(_("confirm failed, no binding found")); ++ end_opt6(o1); ++ return 1; ++ } ++ } + + for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end)) + { + void *ia_option, *ia_end; +@@ -1104,6 +1124,16 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu + good_addr = 1; + log6_quiet(state, "DHCPREPLY", &req_addr, state->hostname); + } + -+ if(daemon->bind_mac_with_ip6) { ++ if(daemon->bind_mac_with_ip6) { ++ if (!is_same_net6(&req_addr, &find_config->addr6, 128)) { ++ o1 = new_opt6(OPTION6_STATUS_CODE); ++ put_opt6_short(DHCP6NOTONLINK); ++ put_opt6_string(_("confirm failed, not binding to this address")); ++ end_opt6(o1); ++ return 1; ++ } ++ } + } + } + +@@ -1723,13 +1753,24 @@ static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr + } + + /* make sure address not leased to another CLID/IAID */ +-static int check_address(struct state *state, struct in6_addr *addr) ++static int check_address(struct dhcp_config *config, struct state *state, struct in6_addr *addr, time_t now, int preempte) + { + struct dhcp_lease *lease; + + if (!(lease = lease6_find_by_addr(addr, 128, 0))) + return 1; + ++ if (preempte && daemon->bind_mac_with_ip6) { + // break rfc3315 here + // bind mac address with a lease + if ((state->mac) && !(config->flags & CONFIG_CLID) && @@ -117,19 +209,27 @@ index 400d939..004ebb8 100644 + } + + // what rfc3315 do -+ if (lease->clid_len != state->clid_len || -+ memcmp(lease->clid, state->clid, state->clid_len) != 0 || -+ lease->iaid != state->iaid) -+ { -+ return 0; -+ } -+ -+ return 1; -+} -+ - static struct dhcp_netid *add_options(struct state *state, int do_refresh) + if (lease->clid_len != state->clid_len || + memcmp(lease->clid, state->clid, state->clid_len) != 0 || + lease->iaid != state->iaid) +@@ -1769,7 +1810,7 @@ static struct addrlist *config_implies(struct dhcp_config *config, struct dhcp_c + return NULL; + } + +-static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now) ++static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now, int preempte) { - void *oro; + u64 addrpart, i, addresses; + struct addrlist *addr_list; +@@ -1803,7 +1844,7 @@ static int config_valid(struct dhcp_config *config, struct dhcp_context *context + { + setaddr6part(addr, addrpart+i); + +- if (check_address(state, addr)) ++ if (check_address(config, state, addr, now, preempte)) + return 1; + } + } -- 2.33.0 diff --git a/backport-Fix-possible-SIGSEGV-in-bpf.c.patch b/backport-Fix-possible-SIGSEGV-in-bpf.c.patch new file mode 100644 index 0000000000000000000000000000000000000000..4332495e7a2f31c766eb4cb51601314f47b4d555 --- /dev/null +++ b/backport-Fix-possible-SIGSEGV-in-bpf.c.patch @@ -0,0 +1,215 @@ +From 535be2f5d355d61332043c7fdc06e095e52a3937 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Sat, 8 Feb 2025 22:58:42 +0000 +Subject: [PATCH] Fix possible SIGSEGV in bpf.c + +Conflict:Context adaptation +Reference:https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=patch;h=535be2f5d355d61332043c7fdc06e095e52a3937 + +--- + src/bpf.c | 170 ++++++++++++++++++++++++++---------------------------- + 1 file changed, 83 insertions(+), 87 deletions(-) + +diff --git a/src/bpf.c b/src/bpf.c +index 15c42fc..4620b3f 100644 +--- a/src/bpf.c ++++ b/src/bpf.c +@@ -126,112 +126,108 @@ int iface_enumerate(int family, void *parm, int (*callback)()) + + for (addrs = head; addrs; addrs = addrs->ifa_next) + { +- if (addrs->ifa_addr->sa_family == family) +- { +- int iface_index = if_nametoindex(addrs->ifa_name); +- +- if (iface_index == 0 || !addrs->ifa_addr || +- (!addrs->ifa_netmask && family != AF_LINK)) +- continue; ++ int iface_index = if_nametoindex(addrs->ifa_name); + +- if (family == AF_INET) +- { +- struct in_addr addr, netmask, broadcast; +- addr = ((struct sockaddr_in *) addrs->ifa_addr)->sin_addr; ++ if (iface_index == 0 || !addrs->ifa_addr || ++ addrs->ifa_addr->sa_family != family || ++ (!addrs->ifa_netmask && family != AF_LINK)) ++ continue; ++ if (family == AF_INET) ++ { ++ struct in_addr addr, netmask, broadcast; ++ addr = ((struct sockaddr_in *) addrs->ifa_addr)->sin_addr; + #ifdef HAVE_BSD_NETWORK +- if (del_family == AF_INET && del_addr.addr4.s_addr == addr.s_addr) +- continue; ++ if (del_family == AF_INET && del_addr.addr4.s_addr == addr.s_addr) ++ continue; + #endif +- netmask = ((struct sockaddr_in *) addrs->ifa_netmask)->sin_addr; +- if (addrs->ifa_broadaddr) +- broadcast = ((struct sockaddr_in *) addrs->ifa_broadaddr)->sin_addr; +- else +- broadcast.s_addr = 0; +- if (!((*callback)(addr, iface_index, NULL, netmask, broadcast, parm))) +- goto err; +- } +- else if (family == AF_INET6) +- { +- struct in6_addr *addr = &((struct sockaddr_in6 *) addrs->ifa_addr)->sin6_addr; +- unsigned char *netmask = (unsigned char *) &((struct sockaddr_in6 *) addrs->ifa_netmask)->sin6_addr; +- int scope_id = ((struct sockaddr_in6 *) addrs->ifa_addr)->sin6_scope_id; +- int i, j, prefix = 0; +- u32 valid = 0xffffffff, preferred = 0xffffffff; +- int flags = 0; ++ netmask = ((struct sockaddr_in *) addrs->ifa_netmask)->sin_addr; ++ if (addrs->ifa_broadaddr) ++ broadcast = ((struct sockaddr_in *) addrs->ifa_broadaddr)->sin_addr; ++ else ++ broadcast.s_addr = 0; ++ if (!callback.af_inet(addr, iface_index, NULL, netmask, broadcast, parm)) ++ goto err; ++ } ++ else if (family == AF_INET6) ++ { ++ struct in6_addr *addr = &((struct sockaddr_in6 *) addrs->ifa_addr)->sin6_addr; ++ unsigned char *netmask = (unsigned char *) &((struct sockaddr_in6 *) addrs->ifa_netmask)->sin6_addr; ++ int scope_id = ((struct sockaddr_in6 *) addrs->ifa_addr)->sin6_scope_id; ++ int i, j, prefix = 0; ++ u32 valid = 0xffffffff, preferred = 0xffffffff; ++ int flags = 0; + #ifdef HAVE_BSD_NETWORK +- if (del_family == AF_INET6 && IN6_ARE_ADDR_EQUAL(&del_addr.addr6, addr)) +- continue; ++ if (del_family == AF_INET6 && IN6_ARE_ADDR_EQUAL(&del_addr.addr6, addr)) ++ continue; + #endif + #if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__) +- struct in6_ifreq ifr6; +- +- memset(&ifr6, 0, sizeof(ifr6)); +- safe_strncpy(ifr6.ifr_name, addrs->ifa_name, sizeof(ifr6.ifr_name)); ++ struct in6_ifreq ifr6; ++ ++ memset(&ifr6, 0, sizeof(ifr6)); ++ safe_strncpy(ifr6.ifr_name, addrs->ifa_name, sizeof(ifr6.ifr_name)); ++ ++ ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr); ++ if (fd != -1 && ioctl(fd, SIOCGIFAFLAG_IN6, &ifr6) != -1) ++ { ++ if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_TENTATIVE) ++ flags |= IFACE_TENTATIVE; + +- ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr); +- if (fd != -1 && ioctl(fd, SIOCGIFAFLAG_IN6, &ifr6) != -1) +- { +- if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_TENTATIVE) +- flags |= IFACE_TENTATIVE; +- +- if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DEPRECATED) +- flags |= IFACE_DEPRECATED; ++ if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DEPRECATED) ++ flags |= IFACE_DEPRECATED; + + #ifdef IN6_IFF_TEMPORARY +- if (!(ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_AUTOCONF | IN6_IFF_TEMPORARY))) +- flags |= IFACE_PERMANENT; ++ if (!(ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_AUTOCONF | IN6_IFF_TEMPORARY))) ++ flags |= IFACE_PERMANENT; + #endif + + #ifdef IN6_IFF_PRIVACY +- if (!(ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_AUTOCONF | IN6_IFF_PRIVACY))) +- flags |= IFACE_PERMANENT; +-#endif +- } +- +- ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr); +- if (fd != -1 && ioctl(fd, SIOCGIFALIFETIME_IN6, &ifr6) != -1) +- { +- valid = ifr6.ifr_ifru.ifru_lifetime.ia6t_vltime; +- preferred = ifr6.ifr_ifru.ifru_lifetime.ia6t_pltime; +- } ++ if (!(ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_AUTOCONF | IN6_IFF_PRIVACY))) ++ flags |= IFACE_PERMANENT; + #endif +- +- for (i = 0; i < IN6ADDRSZ; i++, prefix += 8) +- if (netmask[i] != 0xff) +- break; +- +- if (i != IN6ADDRSZ && netmask[i]) +- for (j = 7; j > 0; j--, prefix++) +- if ((netmask[i] & (1 << j)) == 0) +- break; +- +- /* voodoo to clear interface field in address */ +- if (!option_bool(OPT_NOWILD) && IN6_IS_ADDR_LINKLOCAL(addr)) +- { +- addr->s6_addr[2] = 0; +- addr->s6_addr[3] = 0; +- } +- +- if (!((*callback)(addr, prefix, scope_id, iface_index, flags, +- (int) preferred, (int)valid, parm))) +- goto err; +- } + +-#ifdef HAVE_DHCP6 +- else if (family == AF_LINK) +- { +- /* Assume ethernet again here */ +- struct sockaddr_dl *sdl = (struct sockaddr_dl *) addrs->ifa_addr; +- if (sdl->sdl_alen != 0 && +- !((*callback)(iface_index, ARPHRD_ETHER, LLADDR(sdl), sdl->sdl_alen, parm))) +- goto err; ++ ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr); ++ if (fd != -1 && ioctl(fd, SIOCGIFALIFETIME_IN6, &ifr6) != -1) ++ { ++ valid = ifr6.ifr_ifru.ifru_lifetime.ia6t_vltime; ++ preferred = ifr6.ifr_ifru.ifru_lifetime.ia6t_pltime; + } +-#endif ++#endif ++ ++ for (i = 0; i < IN6ADDRSZ; i++, prefix += 8) ++ if (netmask[i] != 0xff) ++ break; ++ ++ if (i != IN6ADDRSZ && netmask[i]) ++ for (j = 7; j > 0; j--, prefix++) ++ if ((netmask[i] & (1 << j)) == 0) ++ break; ++ ++ /* voodoo to clear interface field in address */ ++ if (!option_bool(OPT_NOWILD) && IN6_IS_ADDR_LINKLOCAL(addr)) ++ { ++ addr->s6_addr[2] = 0; ++ addr->s6_addr[3] = 0; ++ } ++ ++ if (!callback.af_inet6(addr, prefix, scope_id, iface_index, flags, ++ (unsigned int) preferred, (unsigned int)valid, parm)) ++ goto err; ++ } ++ ++#ifdef HAVE_DHCP6 ++ else if (family == AF_LINK) ++ { ++ /* Assume ethernet again here */ ++ struct sockaddr_dl *sdl = (struct sockaddr_dl *) addrs->ifa_addr; ++ if (sdl->sdl_alen != 0 && ++ !callback.af_local(iface_index, ARPHRD_ETHER, LLADDR(sdl), sdl->sdl_alen, parm)) ++ goto err; + } ++#endif + } + + ret = 1; +- ++ + err: + errsave = errno; + freeifaddrs(head); +-- +2.33.0 + diff --git a/backport-Fix-potential-memory-leak.patch b/backport-Fix-potential-memory-leak.patch new file mode 100644 index 0000000000000000000000000000000000000000..9ad0a7be5fa554a08a7b7fde2600cd81e6ac375d --- /dev/null +++ b/backport-Fix-potential-memory-leak.patch @@ -0,0 +1,61 @@ +From efb8f104502c0d8efcd45101a767225042ef21d3 Mon Sep 17 00:00:00 2001 +From: Brian Haley +Date: Thu, 23 Jan 2025 18:26:45 -0500 +Subject: [PATCH] Fix potential memory leak + +When a new IPv6 address is being added to a dhcp_config +struct, if there is anything invalid regarding the prefix +it looks like there is a potential memory leak. +ret_err_free() should be used to free it. + +Also, the new addrlist struct is being linked into +the existing addr6 list in the dhcp_config before the +validity check, it is best to defer this insertion +until later so an invalid entry is not present, since +the CONFIG_ADDR6 flag might not have been set yet. + +Signed-off-by: Brian Haley + +Reference:https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=efb8f104502c0d8efcd45101a767225042ef21d3 +Conflict:NA + +--- + src/option.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/option.c b/src/option.c +index 16afb13..f3dee87 100644 +--- a/src/option.c ++++ b/src/option.c +@@ -4043,10 +4043,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma + } + + new_addr = opt_malloc(sizeof(struct addrlist)); +- new_addr->next = new->addr6; + new_addr->flags = 0; + new_addr->addr.addr6 = in6; +- new->addr6 = new_addr; + + if (pref) + { +@@ -4057,7 +4055,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma + ((((u64)1<<(128-new_addr->prefixlen))-1) & addrpart) != 0) + { + dhcp_config_free(new); +- ret_err(_("bad IPv6 prefix")); ++ ret_err_free(_("bad IPv6 prefix"), new_addr); + } + + new_addr->flags |= ADDRLIST_PREFIX; +@@ -4071,6 +4069,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma + if (i == 8) + new_addr->flags |= ADDRLIST_WILDCARD; + ++ new_addr->next = new->addr6; ++ new->addr6 = new_addr; + new->flags |= CONFIG_ADDR6; + } + #endif +-- +2.33.0 + diff --git a/backport-Update-DNS-records-after-pruning-DHCP-leases.patch b/backport-Update-DNS-records-after-pruning-DHCP-leases.patch new file mode 100644 index 0000000000000000000000000000000000000000..867d8a16707e508b5a8630745db5a89e68b276fd --- /dev/null +++ b/backport-Update-DNS-records-after-pruning-DHCP-leases.patch @@ -0,0 +1,34 @@ +From 80498fab01342243707a482f9b42c38a7c564026 Mon Sep 17 00:00:00 2001 +From: Erik Karlsson +Date: Mon, 29 Apr 2024 20:44:13 +0200 +Subject: [PATCH] Update DNS records after pruning DHCP leases + +Not doing so can result in a use after free since the name for DHCP +derived DNS records is represented as a pointer into the DHCP lease +table. Update will only happen when necessary since lease_update_dns +tests internally on dns_dirty and the force argument is zero. + +Signed-off-by: Erik Karlsson + +Reference:https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=80498fab01342243707a482f9b42c38a7c564026 +Conflict:NA + +--- + src/dnsmasq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/dnsmasq.c b/src/dnsmasq.c +index c14240e..48e402f 100644 +--- a/src/dnsmasq.c ++++ b/src/dnsmasq.c +@@ -1517,6 +1517,7 @@ static void async_event(int pipe, time_t now) + { + lease_prune(NULL, now); + lease_update_file(now); ++ lease_update_dns(0); + } + #ifdef HAVE_DHCP6 + else if (daemon->doing_ra) +-- +2.33.0 + diff --git a/backport-cache-Fix-potential-NULL-deref-in-arcane-situations.patch b/backport-cache-Fix-potential-NULL-deref-in-arcane-situations.patch new file mode 100644 index 0000000000000000000000000000000000000000..8c428ec413e57d6a0aad079665f5535d55fbeb1e --- /dev/null +++ b/backport-cache-Fix-potential-NULL-deref-in-arcane-situations.patch @@ -0,0 +1,28 @@ +From f162d344c03bc9db125084a8f05c9cd7c0c1f4de Mon Sep 17 00:00:00 2001 +From: Matthias Andree +Date: Sun, 29 Dec 2024 22:02:21 +0100 +Subject: [PATCH] cache: Fix potential NULL deref in arcane situations. + +Reference:https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=f162d344c03bc9db125084a8f05c9cd7c0c1f4de +Conflict:NA + +--- + src/cache.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/cache.c b/src/cache.c +index 4395fee..f2aecca 100644 +--- a/src/cache.c ++++ b/src/cache.c +@@ -479,7 +479,7 @@ static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned s + if ((crecp->flags & F_FORWARD) && hostname_isequal(cache_get_name(crecp), name)) + { + int rrmatch = 0; +- if (crecp->flags & flags & F_RR) ++ if (addr && (crecp->flags & flags & F_RR)) + { + unsigned short rrc = (crecp->flags & F_KEYTAG) ? crecp->addr.rrblock.rrtype : crecp->addr.rrdata.rrtype; + unsigned short rra = (flags & F_KEYTAG) ? addr->rrblock.rrtype : addr->rrdata.rrtype; +-- +2.33.0 + diff --git a/bugfix-deal-with-CONFRIM-when-binding-mac-with-ipv6.patch b/bugfix-deal-with-CONFRIM-when-binding-mac-with-ipv6.patch deleted file mode 100644 index fdb7109a4a97c6d5d7aa15f0cec25c2142f6bc6c..0000000000000000000000000000000000000000 --- a/bugfix-deal-with-CONFRIM-when-binding-mac-with-ipv6.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 068fe05737fe86185b5d55da7de6ea6b2668c911 Mon Sep 17 00:00:00 2001 -From: liaichun -Date: Mon, 20 Apr 2020 16:17:24 +0800 -Subject: [PATCH] bugfix-deal-with-CONFRIM-when-binding-mac-with-ipv6 - ---- - src/rfc3315.c | 32 +++++++++++++++++++++++++++++++- - 1 file changed, 31 insertions(+), 1 deletion(-) - -diff --git a/src/rfc3315.c b/src/rfc3315.c -index 004ebb8..8c22ded 100644 ---- a/src/rfc3315.c -+++ b/src/rfc3315.c -@@ -1077,12 +1077,32 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu - case DHCP6CONFIRM: - { - int good_addr = 0, bad_addr = 0; -+ int find_bind = 0; -+ struct dhcp_config *find_config = NULL; - - /* set reply message type */ - outmsgtype = DHCP6REPLY; - - log6_quiet(state, "DHCPCONFIRM", NULL, NULL); -- -+ -+ if(daemon->bind_mac_with_ip6) { -+ if(state->mac) { -+ for (find_config = daemon->dhcp_conf; find_config; find_config = find_config->next) -+ if (config_has_mac(find_config, state->mac, state->mac_len, state->mac_type) && have_config(find_config, CONFIG_ADDR6)) { -+ find_bind = 1; -+ break; -+ } -+ } -+ /* requires all mac has binding ipv6 address. */ -+ if (find_bind == 0) { -+ o1 = new_opt6(OPTION6_STATUS_CODE); -+ put_opt6_short(DHCP6NOTONLINK); -+ put_opt6_string(_("confirm failed, no binding found")); -+ end_opt6(o1); -+ return 1; -+ } -+ } -+ - for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end)) - { - void *ia_option, *ia_end; -@@ -1106,6 +1126,16 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu - good_addr = 1; - log6_quiet(state, "DHCPREPLY", &req_addr, state->hostname); - } -+ -+ if(daemon->bind_mac_with_ip6) { -+ if (!is_same_net6(&req_addr, &find_config->addr6, 128)) { -+ o1 = new_opt6(OPTION6_STATUS_CODE); -+ put_opt6_short(DHCP6NOTONLINK); -+ put_opt6_string(_("confirm failed, not binding to this address")); -+ end_opt6(o1); -+ return 1; -+ } -+ } - } - } - --- -2.33.0 - diff --git a/dnsmasq.spec b/dnsmasq.spec index 226582556224434f34f51ec0d57e48b82f288df2..a43b57a42677c609a1bf75f387160ebd1b362d07 100644 --- a/dnsmasq.spec +++ b/dnsmasq.spec @@ -1,6 +1,6 @@ Name: dnsmasq Version: 2.90 -Release: 3 +Release: 4 Summary: Dnsmasq provides network infrastructure for small networks License: GPLv2 or GPLv3 URL: http://www.thekelleys.org.uk/dnsmasq/ @@ -13,11 +13,15 @@ Patch2: backport-dnsmasq-2.81-configuration.patch Patch3: backport-dnsmasq-2.78-fips.patch Patch4: backport-Fix-spurious-resource-limit-exceeded-messages.patch Patch5: backport-Fix-error-introduced-in-51471cafa5a4fa44d6fe49.patch -Patch6: bugfix-allow-binding-mac-with-ipv6.patch -Patch7: bugfix-deal-with-CONFRIM-when-binding-mac-with-ipv6.patch -Patch8: backport-Fix-crash-when-reloading-DHCP-config-on-SIGHUP.patch -Patch9: backport-Fix-out-of-bounds-heap-read-in-order_qsort.patch -Patch10: backport-Fix-buffer-overflow-when-configured-lease-change-scr.patch +Patch6: backport-Fix-crash-when-reloading-DHCP-config-on-SIGHUP.patch +Patch7: backport-Fix-out-of-bounds-heap-read-in-order_qsort.patch +Patch8: backport-Fix-buffer-overflow-when-configured-lease-change-scr.patch +Patch9: backport-Update-DNS-records-after-pruning-DHCP-leases.patch +Patch10: backport-cache-Fix-potential-NULL-deref-in-arcane-situations.patch +Patch11: backport-Fix-potential-memory-leak.patch +Patch12: backport-Fix-possible-SIGSEGV-in-bpf.c.patch + +Patch9000: allow-binding-mac-with-ip6.patch BuildRequires: gcc BuildRequires: dbus-devel pkgconfig libidn2-devel nettle-devel systemd @@ -107,6 +111,16 @@ install -Dpm644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysusersdir}/dnsmasq.conf %{_mandir}/man8/dnsmasq* %changelog +* Thu Mar 20 2025 lingsheng - 2.90-4 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:Update DNS records after pruning DHCP leases + cache: Fix potential NULL deref in arcane situations. + Fix potential memory leak + Fix possible SIGSEGV in bpf.c + allow binding mac with ip6 + * Thu Dec 12 2024 huyizhen - 2.90-3 - Type:bugfix - CVE: