]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix ipset module for name too long checks, race conditions
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 27 May 2026 11:34:32 +0000 (13:34 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 27 May 2026 11:34:32 +0000 (13:34 +0200)
  on local name buffer, and for socket close race condition.
  Thanks to Qifan Zhang, Palo Alto Networks, for the report.

doc/Changelog
ipset/ipset.c

index bb9452922e1c07e5d492273ab7babef6c73d5b24..7774ee2fd7e8a31c1f5aafbcba32c71324da4a1d 100644 (file)
@@ -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
index 1ad2c09f46daa4c516cb2b2434ce7dd96d9adaec..47740447ac2fe305bd18604a487f62cede7c9c5c 100644 (file)
@@ -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;