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

This commit is contained in:
lingsheng 2025-03-20 15:01:37 +08:00
parent a70dd4f88a
commit 473fce99de
8 changed files with 593 additions and 208 deletions

View File

@ -0,0 +1,235 @@
From 271510e5f7c2130ad4b7e33186e47daf0d3d2d30 Mon Sep 17 00:00:00 2001
From: huyizhen <huyizhen2@huawei.com>
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 | 61 ++++++++++++++++++++++++++++++++++++++++++---------
4 files changed, 58 insertions(+), 11 deletions(-)
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index f3d87cd..3609106 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -281,6 +281,7 @@ int main (int argc, char **argv)
{
daemon->doing_ra = option_bool(OPT_RA);
+ daemon->bind_mac_with_ip6 = option_bool(OPT_BIND_MAC_IP6);
for (context = daemon->dhcp6; context; context = context->next)
{
if (context->flags & CONTEXT_DHCP)
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index e455c3f..ef32f06 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -282,7 +282,8 @@ struct event_desc {
#define OPT_NO_IDENT 70
#define OPT_CACHE_RR 71
#define OPT_LOCALHOST_SERVICE 72
-#define OPT_LAST 73
+#define OPT_BIND_MAC_IP6 73
+#define OPT_LAST 74
#define OPTION_BITS (sizeof(unsigned int)*8)
#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
@@ -1211,6 +1212,7 @@ extern struct daemon {
int override;
int enable_pxe;
int doing_ra, doing_dhcp6;
+ int bind_mac_with_ip6;
struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *dhcp_gen_names;
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 9b5066e..7c316b9 100644
--- a/src/option.c
+++ b/src/option.c
@@ -192,6 +192,7 @@ struct myoption {
#define LOPT_NO_DHCP4 383
#define LOPT_MAX_PROCS 384
#define LOPT_DNSSEC_LIMITS 385
+#define LOPT_BIND_MAC_IP6 386
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
@@ -388,6 +389,7 @@ static const struct myoption opts[] =
{ "use-stale-cache", 2, 0 , LOPT_STALE_CACHE },
{ "no-ident", 0, 0, LOPT_NO_IDENT },
{ "max-tcp-connections", 1, 0, LOPT_MAX_PROCS },
+ { "bind-mac-with-ip6", 0, 0 , LOPT_BIND_MAC_IP6 },
{ NULL, 0, 0, 0 }
};
@@ -591,6 +593,7 @@ static struct {
{ LOPT_NO_IDENT, OPT_NO_IDENT, NULL, gettext_noop("Do not add CHAOS TXT records."), NULL },
{ LOPT_CACHE_RR, ARG_DUP, "<RR-type>", gettext_noop("Cache this DNS resource record type."), NULL },
{ LOPT_MAX_PROCS, ARG_ONE, "<integer>", gettext_noop("Maximum number of concurrent tcp connections."), NULL },
+ { LOPT_BIND_MAC_IP6, OPT_BIND_MAC_IP6, NULL, gettext_noop("Bind mac with ipv6 address. This is an experimental feature and it conflicts with rfc3315."), NULL },
{ 0, 0, NULL, NULL, NULL }
};
diff --git a/src/rfc3315.c b/src/rfc3315.c
index 400d939..e579494 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -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 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);
@@ -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, 1))
{
mark_config_used(state->context, &addr);
if (have_config(config, CONFIG_TIME))
@@ -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;
/* 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;
@@ -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 (!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) &&
+ 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)
@@ -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)
{
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

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

@ -0,0 +1,28 @@
From f162d344c03bc9db125084a8f05c9cd7c0c1f4de Mon Sep 17 00:00:00 2001
From: Matthias Andree <matthias.andree@gmx.de>
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

View File

@ -1,135 +0,0 @@
From 53e1a09a06e11317bbde0e236837e5daa8d40593 Mon Sep 17 00:00:00 2001
From: liaichun <liaichun@huawei.com>
Date: Mon, 20 Apr 2020 16:06:51 +0800
---
src/dnsmasq.c | 1 +
src/dnsmasq.h | 4 +++-
src/option.c | 3 +++
src/rfc3315.c | 35 ++++++++++++++++++++++++++++++++++-
4 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 5d64ceb..04c3be2 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -281,6 +281,7 @@ int main (int argc, char **argv)
{
daemon->doing_ra = option_bool(OPT_RA);
+ daemon->bind_mac_with_ip6 = option_bool(OPT_BIND_MAC_IP6);
for (context = daemon->dhcp6; context; context = context->next)
{
if (context->flags & CONTEXT_DHCP)
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index e455c3f..ef32f06 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -282,7 +282,8 @@ struct event_desc {
#define OPT_NO_IDENT 70
#define OPT_CACHE_RR 71
#define OPT_LOCALHOST_SERVICE 72
-#define OPT_LAST 73
+#define OPT_BIND_MAC_IP6 73
+#define OPT_LAST 74
#define OPTION_BITS (sizeof(unsigned int)*8)
#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
@@ -1211,6 +1212,7 @@ extern struct daemon {
int override;
int enable_pxe;
int doing_ra, doing_dhcp6;
+ int bind_mac_with_ip6;
struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *dhcp_gen_names;
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
--- a/src/option.c
+++ b/src/option.c
@@ -192,6 +192,7 @@ struct myoption {
#define LOPT_NO_DHCP4 383
#define LOPT_MAX_PROCS 384
#define LOPT_DNSSEC_LIMITS 385
+#define LOPT_BIND_MAC_IP6 386
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
@@ -388,6 +389,7 @@ static const struct myoption opts[] =
{ "use-stale-cache", 2, 0 , LOPT_STALE_CACHE },
{ "no-ident", 0, 0, LOPT_NO_IDENT },
{ "max-tcp-connections", 1, 0, LOPT_MAX_PROCS },
+ { "bind-mac-with-ip6", 0, 0 , LOPT_BIND_MAC_IP6 },
{ NULL, 0, 0, 0 }
};
@@ -591,6 +593,7 @@ static struct {
{ LOPT_NO_IDENT, OPT_NO_IDENT, NULL, gettext_noop("Do not add CHAOS TXT records."), NULL },
{ LOPT_CACHE_RR, ARG_DUP, "<RR-type>", gettext_noop("Cache this DNS resource record type."), NULL },
{ LOPT_MAX_PROCS, ARG_ONE, "<integer>", gettext_noop("Maximum number of concurrent tcp connections."), NULL },
+ { LOPT_BIND_MAC_IP6, OPT_BIND_MAC_IP6, NULL, gettext_noop("Bind mac with ipv6 address. This is an experimental feature and it conflicts with rfc3315."), NULL },
{ 0, 0, NULL, NULL, NULL }
};
diff --git a/src/rfc3315.c b/src/rfc3315.c
index 400d939..004ebb8 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);
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 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
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))
{
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
}
+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;
--
2.33.0

View File

@ -1,67 +0,0 @@
From 068fe05737fe86185b5d55da7de6ea6b2668c911 Mon Sep 17 00:00:00 2001
From: liaichun <liaichun@huawei.com>
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

View File

@ -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 <lingsheng1@h-partners.com> - 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 <huyizhen2@huawei.com> - 2.90-3
- Type:bugfix
- CVE: