Skip to content
This repository was archived by the owner on Mar 8, 2025. It is now read-only.

Commit 8708ff3

Browse files
Florian WestphalMSe1969
authored andcommitted
netfilter: arp_tables: init netns pointer in xt_tgdtor_param struct
commit 212e7f56605ef9688d0846db60c6c6ec06544095 upstream. An earlier commit (1b789577f655060d98d20e, "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 [chil360#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: [email protected] Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]> [bwh: Backported to 3.16: - __arpt_unregister_table() has not been split out of arpt_unregister_table() - Add "net" parameter to arpt_unregister_table() and update its only caller in arptable_filter.c] Signed-off-by: Ben Hutchings <[email protected]>
1 parent 8682bdd commit 8708ff3

File tree

3 files changed

+10
-9
lines changed

3 files changed

+10
-9
lines changed

include/linux/netfilter_arp/arp_tables.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ extern void *arpt_alloc_initial_table(const struct xt_table *);
5151
extern struct xt_table *arpt_register_table(struct net *net,
5252
const struct xt_table *table,
5353
const struct arpt_replace *repl);
54-
extern void arpt_unregister_table(struct xt_table *table);
54+
extern void arpt_unregister_table(struct net *, struct xt_table *table);
5555
extern unsigned int arpt_do_table(struct sk_buff *skb,
5656
unsigned int hook,
5757
const struct net_device *in,

net/ipv4/netfilter/arp_tables.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -596,12 +596,13 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
596596
return 0;
597597
}
598598

599-
static inline void cleanup_entry(struct arpt_entry *e)
599+
static void cleanup_entry(struct arpt_entry *e, struct net *net)
600600
{
601601
struct xt_tgdtor_param par;
602602
struct xt_entry_target *t;
603603

604604
t = arpt_get_target(e);
605+
par.net = net;
605606
par.target = t->u.kernel.target;
606607
par.targinfo = t->data;
607608
par.family = NFPROTO_ARP;
@@ -691,7 +692,7 @@ static int translate_table(struct net *net,
691692
xt_entry_foreach(iter, entry0, newinfo->size) {
692693
if (i-- == 0)
693694
break;
694-
cleanup_entry(iter);
695+
cleanup_entry(iter, net);
695696
}
696697
return ret;
697698
}
@@ -1033,7 +1034,7 @@ static int __do_replace(struct net *net, const char *name,
10331034
/* Decrease module usage counts and free resource */
10341035
loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
10351036
xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size)
1036-
cleanup_entry(iter);
1037+
cleanup_entry(iter, net);
10371038

10381039
xt_free_table_info(oldinfo);
10391040
if (copy_to_user(counters_ptr, counters,
@@ -1100,7 +1101,7 @@ static int do_replace(struct net *net, const void __user *user,
11001101

11011102
free_newinfo_untrans:
11021103
xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1103-
cleanup_entry(iter);
1104+
cleanup_entry(iter, net);
11041105
free_newinfo:
11051106
xt_free_table_info(newinfo);
11061107
return ret;
@@ -1414,7 +1415,7 @@ static int compat_do_replace(struct net *net, void __user *user,
14141415

14151416
free_newinfo_untrans:
14161417
xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1417-
cleanup_entry(iter);
1418+
cleanup_entry(iter, net);
14181419
free_newinfo:
14191420
xt_free_table_info(newinfo);
14201421
return ret;
@@ -1691,7 +1692,7 @@ struct xt_table *arpt_register_table(struct net *net,
16911692
return ERR_PTR(ret);
16921693
}
16931694

1694-
void arpt_unregister_table(struct xt_table *table)
1695+
void arpt_unregister_table(struct net *net, struct xt_table *table)
16951696
{
16961697
struct xt_table_info *private;
16971698
void *loc_cpu_entry;
@@ -1703,7 +1704,7 @@ void arpt_unregister_table(struct xt_table *table)
17031704
/* Decrease module usage counts and free resources */
17041705
loc_cpu_entry = private->entries[raw_smp_processor_id()];
17051706
xt_entry_foreach(iter, loc_cpu_entry, private->size)
1706-
cleanup_entry(iter);
1707+
cleanup_entry(iter, net);
17071708
if (private->number > private->initial_entries)
17081709
module_put(table_owner);
17091710
xt_free_table_info(private);

net/ipv4/netfilter/arptable_filter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static int __net_init arptable_filter_net_init(struct net *net)
5353

5454
static void __net_exit arptable_filter_net_exit(struct net *net)
5555
{
56-
arpt_unregister_table(net->ipv4.arptable_filter);
56+
arpt_unregister_table(net, net->ipv4.arptable_filter);
5757
}
5858

5959
static struct pernet_operations arptable_filter_net_ops = {

0 commit comments

Comments
 (0)