!140 [sync] PR-138: Update DNS records after pruning DHCP leases;Fix potential memory leak;Fix possible SIGSEGV in bpf.c;adapt bugfix allow binding mac with ipv6

From: @openeuler-sync-bot 
Reviewed-by: @xiangyu2020 
Signed-off-by: @xiangyu2020
This commit is contained in:
openeuler-ci-bot 2025-03-24 01:32:18 +00:00 committed by Gitee
commit 88206e78f0
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
5 changed files with 473 additions and 1 deletions

View File

@ -0,0 +1,148 @@
From fc7ad95ef2ffd09098a9687f08efb9ef39f5d830 Mon Sep 17 00:00:00 2001
From: huyizhen <huyizhen2@huawei.com>
Date: Thu, 13 Feb 2025 22:41:17 +0800
Subject: [PATCH] adapt bugfix allow binding mac with ipv6
fix bind-mac-with-ip6 function failure.
---
src/rfc3315.c | 62 +++++++++++++++++----------------------------------
1 file changed, 20 insertions(+), 42 deletions(-)
diff --git a/src/rfc3315.c b/src/rfc3315.c
index cdb4b64..e6f3664 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -48,9 +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 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,
unsigned int *min_time, struct in6_addr *addr, time_t now);
@@ -681,7 +680,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);
@@ -690,7 +689,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 */
@@ -705,8 +704,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) &&
- 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))
@@ -862,7 +860,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);
@@ -1319,37 +1317,6 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
}
-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;
-
- if (!(lease = lease6_find_by_addr(addr, 128, 0)))
- {
- return 1;
- }
-
-
- if(daemon->bind_mac_with_ip6) {
- // break rfc3315 here
- // bind mac address with a lease
- if ((state->mac) && !(config->flags & CONFIG_CLID) &&
- config_has_mac(config, state->mac, state->mac_len, state->mac_type)) {
- lease_prune(lease, now);
- return 1;
- }
- }
-
- // 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)
{
void *oro;
@@ -1760,13 +1727,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) &&
+ config_has_mac(config, state->mac, state->mac_len, state->mac_type)) {
+ lease_prune(lease, now);
+ return 1;
+ }
+ }
+
+ // what rfc3315 do
if (lease->clid_len != state->clid_len ||
memcmp(lease->clid, state->clid, state->clid_len) != 0 ||
lease->iaid != state->iaid)
@@ -1806,7 +1784,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)
{
u64 addrpart, i, addresses;
struct addrlist *addr_list;
@@ -1840,7 +1818,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

View File

@ -0,0 +1,215 @@
From 535be2f5d355d61332043c7fdc06e095e52a3937 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
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

View File

@ -0,0 +1,61 @@
From efb8f104502c0d8efcd45101a767225042ef21d3 Mon Sep 17 00:00:00 2001
From: Brian Haley <haleyb.dev@gmail.com>
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 <haleyb.dev@gmail.com>
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

View File

@ -0,0 +1,34 @@
From 80498fab01342243707a482f9b42c38a7c564026 Mon Sep 17 00:00:00 2001
From: Erik Karlsson <erik.karlsson@iopsys.eu>
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 <erik.karlsson@iopsys.eu>
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

View File

@ -1,6 +1,6 @@
Name: dnsmasq
Version: 2.86
Release: 10
Release: 11
Summary: Dnsmasq provides network infrastructure for small networks
License: GPLv2 or GPLv3
URL: http://www.thekelleys.org.uk/dnsmasq/
@ -51,6 +51,11 @@ Patch40: backport-CVE-2023-49441-Fix-standalone-SHA256-implementation.pat
Patch41: backport-Fix-crash-when-reloading-DHCP-config-on-SIGHUP.patch
Patch42: backport-Fix-out-of-bounds-heap-read-in-order_qsort.patch
Patch43: backport-Fix-buffer-overflow-when-configured-lease-change-scr.patch
Patch44: backport-Update-DNS-records-after-pruning-DHCP-leases.patch
Patch45: backport-Fix-potential-memory-leak.patch
Patch46: backport-Fix-possible-SIGSEGV-in-bpf.c.patch
Patch9000: adapt-bugfix-allow-binding-mac-with-ipv6.patch
BuildRequires: gcc
BuildRequires: dbus-devel pkgconfig libidn2-devel nettle-devel systemd
@ -140,6 +145,15 @@ install -Dpm644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysusersdir}/dnsmasq.conf
%{_mandir}/man8/dnsmasq*
%changelog
* Fri Mar 21 2025 lingsheng <lingsheng1@h-partners.com> - 2.86-11
- Type:bugfix
- CVE:NA
- SUG:NA
- DESC:Update DNS records after pruning DHCP leases
Fix potential memory leak
Fix possible SIGSEGV in bpf.c
adapt bugfix allow binding mac with ipv6
* Thu Dec 12 2024 huyizhen <huyizhen2@huawei.com> - 2.86-10
- Type:bugfix
- CVE: