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_