Message ID | 20220824220330.64283-2-pablo@netfilter.org |
---|---|
State | Accepted |
Delegated to: | Pablo Neira |
Headers | show |
Series | [net,01/14] netfilter: ebtables: reject blobs that don't provide all entry points | expand |
Hello: This series was applied to netdev/net.git (master) by Pablo Neira Ayuso <pablo@netfilter.org>: On Thu, 25 Aug 2022 00:03:17 +0200 you wrote: > From: Florian Westphal <fw@strlen.de> > > Harshit Mogalapalli says: > In ebt_do_table() function dereferencing 'private->hook_entry[hook]' > can lead to NULL pointer dereference. [..] Kernel panic: > > general protection fault, probably for non-canonical address 0xdffffc0000000005: 0000 [#1] PREEMPT SMP KASAN > KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f] > [..] > RIP: 0010:ebt_do_table+0x1dc/0x1ce0 > Code: 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 5c 16 00 00 48 b8 00 00 00 00 00 fc ff df 49 8b 6c df 08 48 8d 7d 2c 48 89 fa 48 c1 ea 03 <0f> b6 14 02 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 88 > [..] > Call Trace: > nf_hook_slow+0xb1/0x170 > __br_forward+0x289/0x730 > maybe_deliver+0x24b/0x380 > br_flood+0xc6/0x390 > br_dev_xmit+0xa2e/0x12c0 > > [...] Here is the summary with links: - [net,01/14] netfilter: ebtables: reject blobs that don't provide all entry points https://git.kernel.org/netdev/net/c/7997eff82828 - [net,02/14] netfilter: conntrack: work around exceeded receive window https://git.kernel.org/netdev/net/c/cf97769c761a - [net,03/14] netfilter: nft_tproxy: restrict to prerouting hook https://git.kernel.org/netdev/net/c/18bbc3213383 - [net,04/14] netfilter: nf_tables: disallow updates of implicit chain https://git.kernel.org/netdev/net/c/5dc52d83baac - [net,05/14] netfilter: nf_tables: make table handle allocation per-netns friendly https://git.kernel.org/netdev/net/c/ab482c6b66a4 - [net,06/14] netfilter: nft_payload: report ERANGE for too long offset and length https://git.kernel.org/netdev/net/c/94254f990c07 - [net,07/14] netfilter: nft_payload: do not truncate csum_offset and csum_type https://git.kernel.org/netdev/net/c/7044ab281feb - [net,08/14] netfilter: nf_tables: do not leave chain stats enabled on error https://git.kernel.org/netdev/net/c/43eb8949cfdf - [net,09/14] netfilter: nft_osf: restrict osf to ipv4, ipv6 and inet families https://git.kernel.org/netdev/net/c/5f3b7aae14a7 - [net,10/14] netfilter: nft_tunnel: restrict it to netdev family https://git.kernel.org/netdev/net/c/01e4092d53bc - [net,11/14] netfilter: nf_tables: disallow binding to already bound chain https://git.kernel.org/netdev/net/c/e02f0d397040 - [net,12/14] netfilter: flowtable: add function to invoke garbage collection immediately https://git.kernel.org/netdev/net/c/759eebbcfafc - [net,13/14] netfilter: flowtable: fix stuck flows on cleanup due to pending work https://git.kernel.org/netdev/net/c/9afb4b27349a - [net,14/14] netfilter: nf_defrag_ipv6: allow nf_conntrack_frag6_high_thresh increases https://git.kernel.org/netdev/net/c/00cd7bf9f9e0 You are awesome, thank you!
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index a13296d6c7ce..fd533552a062 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -94,10 +94,6 @@ struct ebt_table { struct ebt_replace_kernel *table; unsigned int valid_hooks; rwlock_t lock; - /* e.g. could be the table explicitly only allows certain - * matches, targets, ... 0 == let it in */ - int (*check)(const struct ebt_table_info *info, - unsigned int valid_hooks); /* the data used by the kernel */ struct ebt_table_info *private; struct nf_hook_ops *ops; diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c index 1a11064f9990..8f19253024b0 100644 --- a/net/bridge/netfilter/ebtable_broute.c +++ b/net/bridge/netfilter/ebtable_broute.c @@ -36,18 +36,10 @@ static struct ebt_replace_kernel initial_table = { .entries = (char *)&initial_chain, }; -static int check(const struct ebt_table_info *info, unsigned int valid_hooks) -{ - if (valid_hooks & ~(1 << NF_BR_BROUTING)) - return -EINVAL; - return 0; -} - static const struct ebt_table broute_table = { .name = "broute", .table = &initial_table, .valid_hooks = 1 << NF_BR_BROUTING, - .check = check, .me = THIS_MODULE, }; diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c index cb949436bc0e..278f324e6752 100644 --- a/net/bridge/netfilter/ebtable_filter.c +++ b/net/bridge/netfilter/ebtable_filter.c @@ -43,18 +43,10 @@ static struct ebt_replace_kernel initial_table = { .entries = (char *)initial_chains, }; -static int check(const struct ebt_table_info *info, unsigned int valid_hooks) -{ - if (valid_hooks & ~FILTER_VALID_HOOKS) - return -EINVAL; - return 0; -} - static const struct ebt_table frame_filter = { .name = "filter", .table = &initial_table, .valid_hooks = FILTER_VALID_HOOKS, - .check = check, .me = THIS_MODULE, }; diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c index 5ee0531ae506..9066f7f376d5 100644 --- a/net/bridge/netfilter/ebtable_nat.c +++ b/net/bridge/netfilter/ebtable_nat.c @@ -43,18 +43,10 @@ static struct ebt_replace_kernel initial_table = { .entries = (char *)initial_chains, }; -static int check(const struct ebt_table_info *info, unsigned int valid_hooks) -{ - if (valid_hooks & ~NAT_VALID_HOOKS) - return -EINVAL; - return 0; -} - static const struct ebt_table frame_nat = { .name = "nat", .table = &initial_table, .valid_hooks = NAT_VALID_HOOKS, - .check = check, .me = THIS_MODULE, }; diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index f2dbefb61ce8..9a0ae59cdc50 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -1040,8 +1040,7 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl, goto free_iterate; } - /* the table doesn't like it */ - if (t->check && (ret = t->check(newinfo, repl->valid_hooks))) + if (repl->valid_hooks != t->valid_hooks) goto free_unlock; if (repl->num_counters && repl->num_counters != t->private->nentries) { @@ -1231,11 +1230,6 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table, if (ret != 0) goto free_chainstack; - if (table->check && table->check(newinfo, table->valid_hooks)) { - ret = -EINVAL; - goto free_chainstack; - } - table->private = newinfo; rwlock_init(&table->lock); mutex_lock(&ebt_mutex);