Skip to content

Commit 2a43ecf

Browse files
Florian Westphalummakynes
Florian Westphal
authored andcommitted
netfilter: nf_tables: avoid global info storage
This works because all accesses are currently serialized by nfnl nf_tables subsys mutex. If we want to have per-netns locking, we need to make this scratch area pernetns or allocate it on demand. This does the latter, its ~28kbyte but we can fallback to vmalloc so it should be fine. Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent be2ab5b commit 2a43ecf

File tree

1 file changed

+12
-16
lines changed

1 file changed

+12
-16
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2454,15 +2454,14 @@ static int nft_table_validate(struct net *net, const struct nft_table *table)
24542454

24552455
#define NFT_RULE_MAXEXPRS 128
24562456

2457-
static struct nft_expr_info *info;
2458-
24592457
static int nf_tables_newrule(struct net *net, struct sock *nlsk,
24602458
struct sk_buff *skb, const struct nlmsghdr *nlh,
24612459
const struct nlattr * const nla[],
24622460
struct netlink_ext_ack *extack)
24632461
{
24642462
const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
24652463
u8 genmask = nft_genmask_next(net);
2464+
struct nft_expr_info *info = NULL;
24662465
int family = nfmsg->nfgen_family;
24672466
struct nft_table *table;
24682467
struct nft_chain *chain;
@@ -2533,6 +2532,12 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
25332532
n = 0;
25342533
size = 0;
25352534
if (nla[NFTA_RULE_EXPRESSIONS]) {
2535+
info = kvmalloc_array(NFT_RULE_MAXEXPRS,
2536+
sizeof(struct nft_expr_info),
2537+
GFP_KERNEL);
2538+
if (!info)
2539+
return -ENOMEM;
2540+
25362541
nla_for_each_nested(tmp, nla[NFTA_RULE_EXPRESSIONS], rem) {
25372542
err = -EINVAL;
25382543
if (nla_type(tmp) != NFTA_LIST_ELEM)
@@ -2625,6 +2630,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
26252630
list_add_rcu(&rule->list, &chain->rules);
26262631
}
26272632
}
2633+
kvfree(info);
26282634
chain->use++;
26292635

26302636
if (net->nft.validate_state == NFT_VALIDATE_DO)
@@ -2638,6 +2644,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
26382644
if (info[i].ops != NULL)
26392645
module_put(info[i].ops->type->owner);
26402646
}
2647+
kvfree(info);
26412648
return err;
26422649
}
26432650

@@ -7203,29 +7210,19 @@ static int __init nf_tables_module_init(void)
72037210

72047211
nft_chain_filter_init();
72057212

7206-
info = kmalloc_array(NFT_RULE_MAXEXPRS, sizeof(struct nft_expr_info),
7207-
GFP_KERNEL);
7208-
if (info == NULL) {
7209-
err = -ENOMEM;
7210-
goto err1;
7211-
}
7212-
72137213
err = nf_tables_core_module_init();
72147214
if (err < 0)
7215-
goto err2;
7215+
return err;
72167216

72177217
err = nfnetlink_subsys_register(&nf_tables_subsys);
72187218
if (err < 0)
7219-
goto err3;
7219+
goto err;
72207220

72217221
register_netdevice_notifier(&nf_tables_flowtable_notifier);
72227222

72237223
return register_pernet_subsys(&nf_tables_net_ops);
7224-
err3:
7224+
err:
72257225
nf_tables_core_module_exit();
7226-
err2:
7227-
kfree(info);
7228-
err1:
72297226
return err;
72307227
}
72317228

@@ -7237,7 +7234,6 @@ static void __exit nf_tables_module_exit(void)
72377234
unregister_pernet_subsys(&nf_tables_net_ops);
72387235
rcu_barrier();
72397236
nf_tables_core_module_exit();
7240-
kfree(info);
72417237
}
72427238

72437239
module_init(nf_tables_module_init);

0 commit comments

Comments
 (0)