Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix handling of empty iptables/ipset/nftables names #2448

Merged
merged 5 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ AC_ARG_ENABLE(stacktrace,
[AS_HELP_STRING([--enable-stacktrace], [compile with stacktrace support])])
AC_ARG_ENABLE(perf,
[AS_HELP_STRING([--enable-perf], [compile with perf performance data recording support for vrrp process])])
AC_ARG_ENABLE(sanitize-address,
[AS_HELP_STRING([--enable-sanitize-address], [compile with sanitize=address (ASAN) support])])
AC_ARG_ENABLE(log-file,
[AS_HELP_STRING([--enable-log-file], [enable logging to file (-g)])])
AC_ARG_ENABLE(dump-threads,
Expand Down Expand Up @@ -2848,6 +2850,16 @@ else
ENABLE_PERF=No
fi

dnl ----[ sanitize=address testing or not? ]----
if test "${enable_sanitize_address}" = yes; then
# AC_DEFINE([_WITH_SANITIZE_ADDRESS_], [ 1 ], [Define to 1 to build with sanitize=address support])
ENABLE_SANITIZE_ADDRESS=Yes
add_config_opt([SANITIZE_ADDRESS])
add_to_var([KA_CFLAGS], [-fsanitize=address -g])
else
ENABLE_SANITIZE_ADDRESS=No
fi

if test "${enable_log_file}" = yes; then
AC_DEFINE([ENABLE_LOG_TO_FILE], [ 1 ], [Define if enabling logging to files])
ENABLE_LOG_FILE_APPEND=Yes
Expand Down Expand Up @@ -3271,6 +3283,9 @@ fi
if test ${ENABLE_PERF} = Yes; then
echo "Perf support : Yes"
fi
if test ${ENABLE_SANITIZE_ADDRESS} = Yes; then
echo "sanitize=address testing : Yes"
fi
if test ${MEM_CHECK} = Yes; then
echo "Memory alloc check : Yes"
echo "Memory alloc check log : ${MEM_CHECK_LOG}"
Expand Down
77 changes: 47 additions & 30 deletions keepalived/core/global_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,32 @@ vrrp_higher_prio_send_advert_handler(const vector_t *strvec)
else
global_data->vrrp_higher_prio_send_advert = true;
}

#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)
{
Expand All @@ -1081,16 +1106,12 @@ vrrp_iptables_handler(const vector_t *strvec)
}

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");
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 (strlen(strvec_slot(strvec,2)) >= XT_EXTENSION_MAXNAMELEN - 1) {
report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : iptables out chain name too long - ignored");
if (!check_valid_iptables_chain_name(strvec, 2, "out chain"))
return;
}
global_data->vrrp_iptables_outchain = STRDUP(strvec_slot(strvec,2));
}
} else {
Expand All @@ -1099,6 +1120,12 @@ vrrp_iptables_handler(const vector_t *strvec)
}
}
#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)
{
Expand All @@ -1119,17 +1146,13 @@ vrrp_ipsets_handler(const vector_t *strvec)
return;
}

if (strlen(strvec_slot(strvec,1)) >= IPSET_MAXNAMELEN - 1) {
report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset address name too long - ignored");
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 (strlen(strvec_slot(strvec,2)) >= IPSET_MAXNAMELEN - 1) {
report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset IPv6 address name too long - ignored");
if (!check_valid_ipset_name(strvec, 2, "IPv6 address"))
return;
}
global_data->vrrp_ipset_address6 = STRDUP(strvec_slot(strvec,2));
} else {
/* No second set specified, copy first name and add "6" */
Expand All @@ -1140,10 +1163,8 @@ vrrp_ipsets_handler(const vector_t *strvec)
}

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");
if (!check_valid_ipset_name(strvec, 3, "IPv6 address_iface"))
return;
}
global_data->vrrp_ipset_address_iface6 = STRDUP(strvec_slot(strvec,3));
} else {
/* No third set specified, copy second name and add "_if6" */
Expand All @@ -1157,10 +1178,8 @@ vrrp_ipsets_handler(const vector_t *strvec)
}

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");
if (!check_valid_ipset_name(strvec, 4, "IGMP"))
return;
}
global_data->vrrp_ipset_igmp = STRDUP(strvec_slot(strvec,4));
} else {
/* No second set specified, copy first name and add "_igmp" */
Expand All @@ -1171,10 +1190,8 @@ vrrp_ipsets_handler(const vector_t *strvec)
}

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");
if (!check_valid_ipset_name(strvec, 5, "MLD"))
return;
}
global_data->vrrp_ipset_mld = STRDUP(strvec_slot(strvec,5));
} else {
/* No second set specified, copy first name and add "_mld" */
Expand All @@ -1186,10 +1203,8 @@ vrrp_ipsets_handler(const vector_t *strvec)

#ifdef _HAVE_VRRP_VMAC_
if (vector_size(strvec) >= 7) {
if (strlen(strvec_slot(strvec,6)) >= IPSET_MAXNAMELEN - 1) {
report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset ND name too long - ignored");
if (!check_valid_ipset_name(strvec, 6, "ND"))
return;
}
global_data->vrrp_ipset_vmac_nd = STRDUP(strvec_slot(strvec,6));
} else {
/* No second set specified, copy first name and add "_nd" */
Expand Down Expand Up @@ -1217,6 +1232,12 @@ vrrp_iptables_handler(__attribute__((unused)) const vector_t *strvec)

#ifdef _WITH_NFTABLES_
#ifdef _WITH_VRRP_
static bool
check_valid_nftables_chain_name(const vector_t *strvec, unsigned entry, const char *log_name)
{
return check_valid_iptables_ipset_nftables_name(strvec, entry, NFT_TABLE_MAXNAMELEN, "nftables", log_name);
}

static void
vrrp_nftables_handler(__attribute__((unused)) const vector_t *strvec)
{
Expand All @@ -1228,10 +1249,8 @@ vrrp_nftables_handler(__attribute__((unused)) const vector_t *strvec)
}

if (vector_size(strvec) >= 2) {
if (strlen(strvec_slot(strvec, 1)) >= NFT_TABLE_MAXNAMELEN) {
report_config_error(CONFIG_GENERAL_ERROR, "nftables table name too long - ignoring");
if (!check_valid_nftables_chain_name(strvec, 1, "chain"))
return;
}
name = strvec_slot(strvec, 1);
}
else {
Expand Down Expand Up @@ -1271,10 +1290,8 @@ ipvs_nftables_handler(__attribute__((unused)) const vector_t *strvec)
}

if (vector_size(strvec) >= 2) {
if (strlen(strvec_slot(strvec, 1)) >= NFT_TABLE_MAXNAMELEN) {
report_config_error(CONFIG_GENERAL_ERROR, "ipvs nftables table name too long - ignoring");
if (!check_valid_nftables_chain_name(strvec, 1, "ipvs chain"))
return;
}
name = strvec_slot(strvec, 1);
}
else {
Expand Down
2 changes: 1 addition & 1 deletion lib/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ static unsigned free_list_size;
static inline int
memcheck_ptr_cmp(const void *key, const struct rb_node *a)
{
return (const char *)key - (char *)rb_entry_const(a, MEMCHECK, t)->ptr;
return less_equal_greater_than((const char *)key, (char *)rb_entry_const(a, MEMCHECK, t)->ptr);
}

static inline bool
Expand Down
Loading