Skip to content

Commit 212e7f5

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: arp_tables: init netns pointer in xt_tgdtor_param struct
An earlier commit (1b78957, "netfilter: arp_tables: init netns pointer in xt_tgchk_param struct") fixed missing net initialization for arptables, but turns out it was incomplete. We can get a very similar struct net NULL deref during error unwinding: general protection fault: 0000 [ctrliq#1] PREEMPT SMP KASAN RIP: 0010:xt_rateest_put+0xa1/0x440 net/netfilter/xt_RATEEST.c:77 xt_rateest_tg_destroy+0x72/0xa0 net/netfilter/xt_RATEEST.c:175 cleanup_entry net/ipv4/netfilter/arp_tables.c:509 [inline] translate_table+0x11f4/0x1d80 net/ipv4/netfilter/arp_tables.c:587 do_replace net/ipv4/netfilter/arp_tables.c:981 [inline] do_arpt_set_ctl+0x317/0x650 net/ipv4/netfilter/arp_tables.c:1461 Also init the netns pointer in xt_tgdtor_param struct. Fixes: add6746 ("netfilter: add struct net * to target parameters") Reported-by: syzbot+91bdd8eece0f6629ec8b@syzkaller.appspotmail.com Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
1 parent c120959 commit 212e7f5

File tree

1 file changed

+10
-9
lines changed

1 file changed

+10
-9
lines changed

net/ipv4/netfilter/arp_tables.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -496,12 +496,13 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
496496
return 0;
497497
}
498498

499-
static inline void cleanup_entry(struct arpt_entry *e)
499+
static void cleanup_entry(struct arpt_entry *e, struct net *net)
500500
{
501501
struct xt_tgdtor_param par;
502502
struct xt_entry_target *t;
503503

504504
t = arpt_get_target(e);
505+
par.net = net;
505506
par.target = t->u.kernel.target;
506507
par.targinfo = t->data;
507508
par.family = NFPROTO_ARP;
@@ -584,7 +585,7 @@ static int translate_table(struct net *net,
584585
xt_entry_foreach(iter, entry0, newinfo->size) {
585586
if (i-- == 0)
586587
break;
587-
cleanup_entry(iter);
588+
cleanup_entry(iter, net);
588589
}
589590
return ret;
590591
}
@@ -927,7 +928,7 @@ static int __do_replace(struct net *net, const char *name,
927928
/* Decrease module usage counts and free resource */
928929
loc_cpu_old_entry = oldinfo->entries;
929930
xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size)
930-
cleanup_entry(iter);
931+
cleanup_entry(iter, net);
931932

932933
xt_free_table_info(oldinfo);
933934
if (copy_to_user(counters_ptr, counters,
@@ -990,7 +991,7 @@ static int do_replace(struct net *net, const void __user *user,
990991

991992
free_newinfo_untrans:
992993
xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
993-
cleanup_entry(iter);
994+
cleanup_entry(iter, net);
994995
free_newinfo:
995996
xt_free_table_info(newinfo);
996997
return ret;
@@ -1287,7 +1288,7 @@ static int compat_do_replace(struct net *net, void __user *user,
12871288

12881289
free_newinfo_untrans:
12891290
xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1290-
cleanup_entry(iter);
1291+
cleanup_entry(iter, net);
12911292
free_newinfo:
12921293
xt_free_table_info(newinfo);
12931294
return ret;
@@ -1514,7 +1515,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
15141515
return ret;
15151516
}
15161517

1517-
static void __arpt_unregister_table(struct xt_table *table)
1518+
static void __arpt_unregister_table(struct net *net, struct xt_table *table)
15181519
{
15191520
struct xt_table_info *private;
15201521
void *loc_cpu_entry;
@@ -1526,7 +1527,7 @@ static void __arpt_unregister_table(struct xt_table *table)
15261527
/* Decrease module usage counts and free resources */
15271528
loc_cpu_entry = private->entries;
15281529
xt_entry_foreach(iter, loc_cpu_entry, private->size)
1529-
cleanup_entry(iter);
1530+
cleanup_entry(iter, net);
15301531
if (private->number > private->initial_entries)
15311532
module_put(table_owner);
15321533
xt_free_table_info(private);
@@ -1566,7 +1567,7 @@ int arpt_register_table(struct net *net,
15661567

15671568
ret = nf_register_net_hooks(net, ops, hweight32(table->valid_hooks));
15681569
if (ret != 0) {
1569-
__arpt_unregister_table(new_table);
1570+
__arpt_unregister_table(net, new_table);
15701571
*res = NULL;
15711572
}
15721573

@@ -1581,7 +1582,7 @@ void arpt_unregister_table(struct net *net, struct xt_table *table,
15811582
const struct nf_hook_ops *ops)
15821583
{
15831584
nf_unregister_net_hooks(net, ops, hweight32(table->valid_hooks));
1584-
__arpt_unregister_table(table);
1585+
__arpt_unregister_table(net, table);
15851586
}
15861587

15871588
/* The built-in targets: standard (NULL) and error. */

0 commit comments

Comments
 (0)