From: W.C.A. Wijngaards Date: Wed, 27 May 2026 11:34:32 +0000 (+0200) Subject: - Fix ipset module for name too long checks, race conditions X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0c15ddd133ae46d44ad6d17db419bbad477aab03;p=thirdparty%2Funbound.git - Fix ipset module for name too long checks, race conditions on local name buffer, and for socket close race condition. Thanks to Qifan Zhang, Palo Alto Networks, for the report. --- diff --git a/doc/Changelog b/doc/Changelog index bb9452922..7774ee2fd 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -24,6 +24,9 @@ - Fix that dns64 with subnetcache does not write ECS scoped answers to global cache. Thanks to Qifan Zhang, Palo Alto Networks, for the report. + - Fix ipset module for name too long checks, race conditions + on local name buffer, and for socket close race condition. + Thanks to Qifan Zhang, Palo Alto Networks, for the report. 26 May 2026: Wouter - Fix for mesh new client and mesh new callback to rollback the diff --git a/ipset/ipset.c b/ipset/ipset.c index 1ad2c09f4..47740447a 100644 --- a/ipset/ipset.c +++ b/ipset/ipset.c @@ -143,7 +143,7 @@ static int add_to_ipset(filter_dev dev, const char *setname, const void *ipaddr, struct nlmsghdr *nlh; struct nfgenmsg *nfg; struct nlattr *nested[2]; - static char buffer[BUFF_LEN]; + char buffer[BUFF_LEN]; if (strlen(setname) >= IPSET_MAXNAMELEN) { errno = ENAMETOOLONG; @@ -208,13 +208,6 @@ ipset_add_rrset_data(struct ipset_env *ie, ret = add_to_ipset((filter_dev)ie->dev, setname, rr_data + 2, af); if (ret < 0) { log_err("ipset: could not add %s into %s", dname, setname); - -#if HAVE_NET_PFVAR_H - /* don't close as we might not be able to open again due to dropped privs */ -#else - mnl_socket_close((filter_dev)ie->dev); - ie->dev = NULL; -#endif break; } } @@ -226,7 +219,7 @@ ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie, struct ub_packed_rrset_key *rrset, const char *qname, int qlen, const char *setname, int af) { - static char dname[BUFF_LEN]; + char dname[BUFF_LEN]; const char *ds, *qs; int dlen, plen; @@ -276,7 +269,7 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg, const char *setname; struct ub_packed_rrset_key *rrset; int af; - static char qname[BUFF_LEN]; + char qname[BUFF_LEN]; int qlen; #ifdef HAVE_NET_PFVAR_H @@ -372,6 +365,16 @@ int ipset_init(struct module_env* env, int id) { ipset_env->name_v4 = env->cfg->ipset_name_v4; ipset_env->name_v6 = env->cfg->ipset_name_v6; +#ifndef HAVE_NET_PFVAR_H + if (ipset_env->name_v4 && strlen(ipset_env->name_v4) >= IPSET_MAXNAMELEN) { + log_err("ipset: name-v4 exceeds IPSET_MAXNAMELEN (%d)", IPSET_MAXNAMELEN); + return 0; + } + if (ipset_env->name_v6 && strlen(ipset_env->name_v6) >= IPSET_MAXNAMELEN) { + log_err("ipset: name-v6 exceeds IPSET_MAXNAMELEN (%d)", IPSET_MAXNAMELEN); + return 0; + } +#endif ipset_env->v4_enabled = !ipset_env->name_v4 || (strlen(ipset_env->name_v4) == 0) ? 0 : 1; ipset_env->v6_enabled = !ipset_env->name_v6 || (strlen(ipset_env->name_v6) == 0) ? 0 : 1;