File bsc-1228123.patch of Package keepalived.35326

--- keepalived-2.2.8-orig/keepalived/core/global_parser.c	2023-04-01 19:39:25.000000000 +0200
+++ keepalived-2.2.8/keepalived/core/global_parser.c	2024-09-10 10:16:41.921207664 +0200
@@ -1058,117 +1058,171 @@
 	else
 		global_data->vrrp_higher_prio_send_advert = true;
 }
-#ifdef _WITH_IPTABLES_
+#if defined _WITH_IPTABLES_ || defined _WITH_NFTABLES_
+static bool
+check_valid_iptables_ipset_nftables_name(const vector_t *strvec, unsigned entry, unsigned max_len, const char *type_name, const char *log_name)
+{
+        if (strlen(strvec_slot(strvec, entry)) >= max_len - 1) {
+                report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : %s %s name too long - ignored", type_name, log_name);
+                return false;
+        }
+
+        if (strlen(strvec_slot(strvec, entry)) == 0) {
+                report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : %s %s name empty - ignored", type_name, log_name);
+                return false;
+        }
+
+        return true;
+}
+#endif  
+
+#ifdef _WITH_IPTABLES_  
+static bool     
+check_valid_iptables_chain_name(const vector_t *strvec, unsigned entry, const char *log_name)
+{
+        return check_valid_iptables_ipset_nftables_name(strvec, entry, XT_EXTENSION_MAXNAMELEN, "iptables", log_name);
+}
+
 static void
-vrrp_iptables_handler(const vector_t *strvec)
+vrrp_iptables_handler(const vector_t *strvec) 
 {
-	if (global_data->vrrp_iptables_inchain) {
-		report_config_error(CONFIG_GENERAL_ERROR, "iptables already specified - ignoring");
-		return;
-	}
-
-	if (vector_size(strvec) >= 2) {
-		if (strlen(strvec_slot(strvec,1)) >= XT_EXTENSION_MAXNAMELEN - 1) {
-			report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : iptables in chain name too long - ignored");
-			return;
-		}
-		global_data->vrrp_iptables_inchain = STRDUP(strvec_slot(strvec,1));
-		if (vector_size(strvec) >= 3) {
-			if (strlen(strvec_slot(strvec,2)) >= XT_EXTENSION_MAXNAMELEN - 1) {
-				report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : iptables out chain name too long - ignored");
-				return;
-			}
-			global_data->vrrp_iptables_outchain = STRDUP(strvec_slot(strvec,2));
-		}
-	} else {
-		global_data->vrrp_iptables_inchain = STRDUP(DEFAULT_IPTABLES_CHAIN_IN);
-		global_data->vrrp_iptables_outchain = STRDUP(DEFAULT_IPTABLES_CHAIN_OUT);
-	}
+        if (global_data->vrrp_iptables_inchain) {
+                report_config_error(CONFIG_GENERAL_ERROR, "iptables already specified - ignoring");
+                return;
+        }
+
+        if (vector_size(strvec) >= 2) {
+                if (!check_valid_iptables_chain_name(strvec, 1, "in chain"))
+                        return;
+                global_data->vrrp_iptables_inchain = STRDUP(strvec_slot(strvec,1));
+                if (vector_size(strvec) >= 3) {
+                        if (!check_valid_iptables_chain_name(strvec, 2, "out chain"))
+                                return;
+
+                        if (!strcmp(global_data->vrrp_iptables_inchain, strvec_slot(strvec, 2))) {
+                                log_message(LOG_INFO, "vrrp_iptables: chain names cannot be the same");
+                                FREE_CONST_PTR(global_data->vrrp_iptables_inchain);
+
+                                return;
+                        }
+                        global_data->vrrp_iptables_outchain = STRDUP(strvec_slot(strvec,2));
+                }
+
+                return;
+        }
+
+        global_data->vrrp_iptables_inchain = STRDUP(DEFAULT_IPTABLES_CHAIN_IN);
+        global_data->vrrp_iptables_outchain = STRDUP(DEFAULT_IPTABLES_CHAIN_OUT);
 }
+
 #ifdef _HAVE_LIBIPSET_
+static bool
+check_valid_ipset_name(const vector_t *strvec, unsigned entry, const char *log_name)
+{
+        return check_valid_iptables_ipset_nftables_name(strvec, entry, IPSET_MAXNAMELEN, "ipset", log_name);
+}
+
 static void
 vrrp_ipsets_handler(const vector_t *strvec)
 {
-	size_t len;
-	char set_name[IPSET_MAXNAMELEN];
-
-	FREE_CONST_PTR(global_data->vrrp_ipset_address);
-	FREE_CONST_PTR(global_data->vrrp_ipset_address6);
-	FREE_CONST_PTR(global_data->vrrp_ipset_address_iface6);
-	FREE_CONST_PTR(global_data->vrrp_ipset_igmp);
-	FREE_CONST_PTR(global_data->vrrp_ipset_mld);
-
-	if (vector_size(strvec) < 2) {
-		global_data->using_ipsets = false;
-		return;
-	}
-
-	if (strlen(strvec_slot(strvec,1)) >= IPSET_MAXNAMELEN - 1) {
-		report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset address name too long - ignored");
-		return;
-	}
-	global_data->vrrp_ipset_address = STRDUP(strvec_slot(strvec,1));
-
-	if (vector_size(strvec) >= 3) {
-		if (strlen(strvec_slot(strvec,2)) >= IPSET_MAXNAMELEN - 1) {
-			report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset IPv6 address name too long - ignored");
-			return;
-		}
-		global_data->vrrp_ipset_address6 = STRDUP(strvec_slot(strvec,2));
-	}
-	else {
-		/* No second set specified, copy first name and add "6" */
-		strcpy_safe(set_name, global_data->vrrp_ipset_address);
-		set_name[IPSET_MAXNAMELEN - 2] = '\0';
-		strcat(set_name, "6");
-		global_data->vrrp_ipset_address6 = STRDUP(set_name);
-	}
-	if (vector_size(strvec) >= 4) {
-		if (strlen(strvec_slot(strvec,3)) >= IPSET_MAXNAMELEN - 1) {
-			report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset IPv6 address_iface name too long - ignored");
-			return;
-		}
-		global_data->vrrp_ipset_address_iface6 = STRDUP(strvec_slot(strvec,3));
-	}
-	else {
-		/* No third set specified, copy second name and add "_if6" */
-		strcpy_safe(set_name, global_data->vrrp_ipset_address6);
-		len = strlen(set_name);
-		if (set_name[len-1] == '6')
-			set_name[--len] = '\0';
-		set_name[IPSET_MAXNAMELEN - 5] = '\0';
-		strcat(set_name, "_if6");
-		global_data->vrrp_ipset_address_iface6 = STRDUP(set_name);
-	}
-
-	if (vector_size(strvec) >= 5) {
-		if (strlen(strvec_slot(strvec,4)) >= IPSET_MAXNAMELEN - 1) {
-			report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset IGMP name too long - ignored");
-			return;
-		}
-		global_data->vrrp_ipset_igmp = STRDUP(strvec_slot(strvec,4));
-	}
-	else {
-		/* No second set specified, copy first name and add "_igmp" */
-		strcpy_safe(set_name, global_data->vrrp_ipset_address);
-		set_name[sizeof(set_name) - 6] = '\0';
-		strcat(set_name, "_igmp");
-		global_data->vrrp_ipset_igmp = STRDUP(set_name);
-	}
-	if (vector_size(strvec) >= 6) {
-		if (strlen(strvec_slot(strvec,5)) >= IPSET_MAXNAMELEN - 1) {
-			report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset MLD name too long - ignored");
-			return;
-		}
-		global_data->vrrp_ipset_mld = STRDUP(strvec_slot(strvec,5));
-	}
-	else {
-		/* No second set specified, copy first name and add "_mld" */
-		strcpy_safe(set_name, global_data->vrrp_ipset_address);
-		set_name[sizeof(set_name) - 5] = '\0';
-		strcat(set_name, "_mld");
-		global_data->vrrp_ipset_mld = STRDUP(set_name);
-	}
+        size_t len;
+        char set_name[IPSET_MAXNAMELEN];
+        unsigned sn0, sn1;
+        const char **set_names[] = {
+                &global_data->vrrp_ipset_address,
+                &global_data->vrrp_ipset_address6,
+                &global_data->vrrp_ipset_address_iface6,
+                &global_data->vrrp_ipset_igmp,
+                &global_data->vrrp_ipset_mld
+                                                };
+
+        FREE_CONST_PTR(global_data->vrrp_ipset_address);
+        FREE_CONST_PTR(global_data->vrrp_ipset_address6);
+        FREE_CONST_PTR(global_data->vrrp_ipset_address_iface6);
+        FREE_CONST_PTR(global_data->vrrp_ipset_igmp);
+        FREE_CONST_PTR(global_data->vrrp_ipset_mld);
+        global_data->using_ipsets = PARAMETER_UNSET;
+
+        if (vector_size(strvec) < 2) {
+                global_data->using_ipsets = false;
+                return;
+        }
+
+        if (!check_valid_ipset_name(strvec, 1, "address"))
+                return;
+        global_data->vrrp_ipset_address = STRDUP(strvec_slot(strvec,1));
+
+        if (vector_size(strvec) >= 3) {
+                if (!check_valid_ipset_name(strvec, 2, "IPv6 address"))
+                        goto ipset_error;
+                global_data->vrrp_ipset_address6 = STRDUP(strvec_slot(strvec,2));
+        } else {
+                /* No second set specified, copy first name and add "6" */
+                strcpy_safe(set_name, global_data->vrrp_ipset_address);
+                set_name[IPSET_MAXNAMELEN - 2] = '\0';
+                strcat(set_name, "6");
+                global_data->vrrp_ipset_address6 = STRDUP(set_name);
+        }
+
+        if (vector_size(strvec) >= 4) {
+                if (!check_valid_ipset_name(strvec, 3, "IPv6 address_iface"))
+                        goto ipset_error;
+                global_data->vrrp_ipset_address_iface6 = STRDUP(strvec_slot(strvec,3));
+        } else {
+                /* No third set specified, copy second name and add "_if6" */
+                strcpy_safe(set_name, global_data->vrrp_ipset_address6);
+                len = strlen(set_name);
+                if (set_name[len-1] == '6')
+                        set_name[--len] = '\0';
+                set_name[IPSET_MAXNAMELEN - 5] = '\0';
+                strcat(set_name, "_if6");
+                global_data->vrrp_ipset_address_iface6 = STRDUP(set_name);
+        }
+
+        if (vector_size(strvec) >= 5) {
+                if (!check_valid_ipset_name(strvec, 4, "IGMP"))
+                        goto ipset_error;
+                global_data->vrrp_ipset_igmp = STRDUP(strvec_slot(strvec,4));
+        } else {
+                /* No second set specified, copy first name and add "_igmp" */
+                strcpy_safe(set_name, global_data->vrrp_ipset_address);
+                set_name[sizeof(set_name) - 6] = '\0';
+                strcat(set_name, "_igmp");
+                global_data->vrrp_ipset_igmp = STRDUP(set_name);
+        }
+
+        if (vector_size(strvec) >= 6) {
+                if (!check_valid_ipset_name(strvec, 5, "MLD"))
+                        goto ipset_error;
+                global_data->vrrp_ipset_mld = STRDUP(strvec_slot(strvec,5));
+        } else {
+                /* No second set specified, copy first name and add "_mld" */
+                strcpy_safe(set_name, global_data->vrrp_ipset_address);
+                set_name[sizeof(set_name) - 5] = '\0';
+                strcat(set_name, "_mld");
+                global_data->vrrp_ipset_mld = STRDUP(set_name);
+        }
+
+        /* Ensure all the set names are different */
+        for (sn0 = 0; sn0 < sizeof(set_names) / sizeof(set_names[0]) - 1; sn0++) {
+                for (sn1 = sn0 + 1; sn1 < sizeof(set_names) / sizeof(set_names[0]); sn1++) {
+                        if (!strcmp(*set_names[sn0], *set_names[sn1])) {
+                                report_config_error(CONFIG_GENERAL_ERROR, "vrrp_ipsets: set name %s used more than once", *set_names[sn0]);
+                                goto ipset_error;
+                        }
+                }
+        }
+
+        global_data->using_ipsets = true;
+
+        return;
+
+ipset_error:
+        FREE_CONST_PTR(global_data->vrrp_ipset_address);
+        FREE_CONST_PTR(global_data->vrrp_ipset_address6);
+        FREE_CONST_PTR(global_data->vrrp_ipset_address_iface6);
+        FREE_CONST_PTR(global_data->vrrp_ipset_igmp);
+        FREE_CONST_PTR(global_data->vrrp_ipset_mld);
 }
 #endif
 #elif defined _WITH_NFTABLES_
openSUSE Build Service is sponsored by