Skip to content

Commit e58a171

Browse files
Florian Westphalummakynes
authored andcommitted
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>
1 parent efb056e commit e58a171

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
@@ -1090,7 +1090,7 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl,
10901090

10911091
audit_log_nfcfg(repl->name, AF_BRIDGE, repl->nentries,
10921092
AUDIT_XT_OP_REPLACE, GFP_KERNEL);
1093-
return ret;
1093+
return 0;
10941094

10951095
free_unlock:
10961096
mutex_unlock(&ebt_mutex);

net/ipv4/netfilter/ip_tables.c

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

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

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

net/ipv6/netfilter/ip6_tables.c

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

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

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

0 commit comments

Comments
 (0)