Skip to content

Commit eaddfeb

Browse files
committed
netfilter: ebtables: fix table blob use-after-free
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2189550 Upstream Status: commit e58a171 commit e58a171 Author: Florian Westphal <fw@strlen.de> Date: Fri Feb 17 23:20:06 2023 +0100 netfilter: ebtables: fix table blob use-after-free We are not allowed to return an error at this point. Looking at the code it looks like ret is always 0 at this point, but its not. t = find_table_lock(net, repl->name, &ret, &ebt_mutex); ... this can return a valid table, with ret != 0. This bug causes update of table->private with the new blob, but then frees the blob right away in the caller. Syzbot report: BUG: KASAN: vmalloc-out-of-bounds in __ebt_unregister_table+0xc00/0xcd0 net/bridge/netfilter/ebtables.c:1168 Read of size 4 at addr ffffc90005425000 by task kworker/u4:4/74 Workqueue: netns cleanup_net Call Trace: kasan_report+0xbf/0x1f0 mm/kasan/report.c:517 __ebt_unregister_table+0xc00/0xcd0 net/bridge/netfilter/ebtables.c:1168 ebt_unregister_table+0x35/0x40 net/bridge/netfilter/ebtables.c:1372 ops_exit_list+0xb0/0x170 net/core/net_namespace.c:169 cleanup_net+0x4ee/0xb10 net/core/net_namespace.c:613 ... ip(6)tables appears to be ok (ret should be 0 at this point) but make this more obvious. Fixes: c58dd2d ("netfilter: Can't fail and free after table replacement") Reported-by: syzbot+f61594de72d6705aea03@syzkaller.appspotmail.com Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Florian Westphal <fwestpha@redhat.com>
1 parent 637c557 commit eaddfeb

File tree

3 files changed

+3
-5
lines changed

3 files changed

+3
-5
lines changed

net/bridge/netfilter/ebtables.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,7 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl,
10531053

10541054
audit_log_nfcfg(repl->name, AF_BRIDGE, repl->nentries,
10551055
AUDIT_XT_OP_REPLACE, GFP_KERNEL);
1056-
return ret;
1056+
return 0;
10571057

10581058
free_unlock:
10591059
mutex_unlock(&ebt_mutex);

net/ipv4/netfilter/ip_tables.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,7 +1044,6 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
10441044
struct xt_counters *counters;
10451045
struct ipt_entry *iter;
10461046

1047-
ret = 0;
10481047
counters = xt_counters_alloc(num_counters);
10491048
if (!counters) {
10501049
ret = -ENOMEM;
@@ -1090,7 +1089,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
10901089
net_warn_ratelimited("iptables: counters copy to user failed while replacing table\n");
10911090
}
10921091
vfree(counters);
1093-
return ret;
1092+
return 0;
10941093

10951094
put_module:
10961095
module_put(t->me);

net/ipv6/netfilter/ip6_tables.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,7 +1061,6 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
10611061
struct xt_counters *counters;
10621062
struct ip6t_entry *iter;
10631063

1064-
ret = 0;
10651064
counters = xt_counters_alloc(num_counters);
10661065
if (!counters) {
10671066
ret = -ENOMEM;
@@ -1107,7 +1106,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
11071106
net_warn_ratelimited("ip6tables: counters copy to user failed while replacing table\n");
11081107
}
11091108
vfree(counters);
1110-
return ret;
1109+
return 0;
11111110

11121111
put_module:
11131112
module_put(t->me);

0 commit comments

Comments
 (0)