From 47a6959fa331fe892a4fc3b48ca08e92045c6bda Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 26 Apr 2021 12:14:40 +0200 Subject: netfilter: allow to turn off xtables compat layer The compat layer needs to parse untrusted input (the ruleset) to translate it to a 64bit compatible format. We had a number of bugs in this department in the past, so allow users to turn this feature off. Add CONFIG_NETFILTER_XTABLES_COMPAT kconfig knob and make it default to y to keep existing behaviour. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/netfilter/Kconfig | 10 ++++++++++ net/netfilter/x_tables.c | 16 ++++++++-------- net/netfilter/xt_limit.c | 6 +++--- 3 files changed, 21 insertions(+), 11 deletions(-) (limited to 'net/netfilter') diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index fcd8682704c4..56a2531a3402 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -728,6 +728,16 @@ config NETFILTER_XTABLES if NETFILTER_XTABLES +config NETFILTER_XTABLES_COMPAT + bool "Netfilter Xtables 32bit support" + depends on COMPAT + default y + help + This option provides a translation layer to run 32bit arp,ip(6),ebtables + binaries on 64bit kernels. + + If unsure, say N. + comment "Xtables combined modules" config NETFILTER_XT_MARK diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index ef37deff8405..84e58ee501a4 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -52,7 +52,7 @@ struct xt_af { struct mutex mutex; struct list_head match; struct list_head target; -#ifdef CONFIG_COMPAT +#ifdef CONFIG_NETFILTER_XTABLES_COMPAT struct mutex compat_mutex; struct compat_delta *compat_tab; unsigned int number; /* number of slots in compat_tab[] */ @@ -647,7 +647,7 @@ static bool error_tg_ok(unsigned int usersize, unsigned int kernsize, return usersize == kernsize && strnlen(msg, msglen) < msglen; } -#ifdef CONFIG_COMPAT +#ifdef CONFIG_NETFILTER_XTABLES_COMPAT int xt_compat_add_offset(u_int8_t af, unsigned int offset, int delta) { struct xt_af *xp = &xt[af]; @@ -850,7 +850,7 @@ int xt_compat_check_entry_offsets(const void *base, const char *elems, __alignof__(struct compat_xt_entry_match)); } EXPORT_SYMBOL(xt_compat_check_entry_offsets); -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_NETFILTER_XTABLES_COMPAT */ /** * xt_check_entry_offsets - validate arp/ip/ip6t_entry @@ -868,7 +868,7 @@ EXPORT_SYMBOL(xt_compat_check_entry_offsets); * match structures are aligned, and that the last structure ends where * the target structure begins. * - * Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version. + * Also see xt_compat_check_entry_offsets for CONFIG_NETFILTER_XTABLES_COMPAT version. * * The arp/ip/ip6t_entry structure @base must have passed following tests: * - it must point to a valid memory location @@ -1059,7 +1059,7 @@ void *xt_copy_counters(sockptr_t arg, unsigned int len, void *mem; u64 size; -#ifdef CONFIG_COMPAT +#ifdef CONFIG_NETFILTER_XTABLES_COMPAT if (in_compat_syscall()) { /* structures only differ in size due to alignment */ struct compat_xt_counters_info compat_tmp; @@ -1106,7 +1106,7 @@ void *xt_copy_counters(sockptr_t arg, unsigned int len, } EXPORT_SYMBOL_GPL(xt_copy_counters); -#ifdef CONFIG_COMPAT +#ifdef CONFIG_NETFILTER_XTABLES_COMPAT int xt_compat_target_offset(const struct xt_target *target) { u_int16_t csize = target->compatsize ? : target->targetsize; @@ -1293,7 +1293,7 @@ void xt_table_unlock(struct xt_table *table) } EXPORT_SYMBOL_GPL(xt_table_unlock); -#ifdef CONFIG_COMPAT +#ifdef CONFIG_NETFILTER_XTABLES_COMPAT void xt_compat_lock(u_int8_t af) { mutex_lock(&xt[af].compat_mutex); @@ -1931,7 +1931,7 @@ static int __init xt_init(void) for (i = 0; i < NFPROTO_NUMPROTO; i++) { mutex_init(&xt[i].mutex); -#ifdef CONFIG_COMPAT +#ifdef CONFIG_NETFILTER_XTABLES_COMPAT mutex_init(&xt[i].compat_mutex); xt[i].compat_tab = NULL; #endif diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c index bd1dea9c7b88..24d4afb9988d 100644 --- a/net/netfilter/xt_limit.c +++ b/net/netfilter/xt_limit.c @@ -134,7 +134,7 @@ static void limit_mt_destroy(const struct xt_mtdtor_param *par) kfree(info->master); } -#ifdef CONFIG_COMPAT +#ifdef CONFIG_NETFILTER_XTABLES_COMPAT struct compat_xt_rateinfo { u_int32_t avg; u_int32_t burst; @@ -176,7 +176,7 @@ static int limit_mt_compat_to_user(void __user *dst, const void *src) }; return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0; } -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_NETFILTER_XTABLES_COMPAT */ static struct xt_match limit_mt_reg __read_mostly = { .name = "limit", @@ -186,7 +186,7 @@ static struct xt_match limit_mt_reg __read_mostly = { .checkentry = limit_mt_check, .destroy = limit_mt_destroy, .matchsize = sizeof(struct xt_rateinfo), -#ifdef CONFIG_COMPAT +#ifdef CONFIG_NETFILTER_XTABLES_COMPAT .compatsize = sizeof(struct compat_xt_rateinfo), .compat_from_user = limit_mt_compat_from_user, .compat_to_user = limit_mt_compat_to_user, -- cgit v1.2.3