summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-04-19 06:43:33 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-04-29 15:41:49 -0400
commit14b872f02ebd6fd451744f71a3d44b0e57e423ca (patch)
treea7e69fbecca8eb2f3e8bb6f304d76abe56fe50c9 /net
parent89b107adce32a52920b36787b60c8f24c986c526 (diff)
downloadlinux-14b872f02ebd6fd451744f71a3d44b0e57e423ca.tar.bz2
xt_hashlimit: allocate a copy of name explicitly, don't rely on procfs guts
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/xt_hashlimit.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index ebfad037b11f..905c328ed5a8 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -107,6 +107,7 @@ struct xt_hashlimit_htable {
/* seq_file stuff */
struct proc_dir_entry *pde;
+ const char *name;
struct net *net;
struct hlist_head hash[0]; /* hashtable itself */
@@ -253,6 +254,11 @@ static int htable_create(struct net *net, struct xt_hashlimit_mtinfo1 *minfo,
hinfo->count = 0;
hinfo->family = family;
hinfo->rnd_initialized = false;
+ hinfo->name = kstrdup(minfo->name, GFP_KERNEL);
+ if (!hinfo->name) {
+ vfree(hinfo);
+ return -ENOMEM;
+ }
spin_lock_init(&hinfo->lock);
hinfo->pde = proc_create_data(minfo->name, 0,
@@ -260,6 +266,7 @@ static int htable_create(struct net *net, struct xt_hashlimit_mtinfo1 *minfo,
hashlimit_net->ipt_hashlimit : hashlimit_net->ip6t_hashlimit,
&dl_file_ops, hinfo);
if (hinfo->pde == NULL) {
+ kfree(hinfo->name);
vfree(hinfo);
return -ENOMEM;
}
@@ -330,9 +337,10 @@ static void htable_destroy(struct xt_hashlimit_htable *hinfo)
parent = hashlimit_net->ip6t_hashlimit;
if(parent != NULL)
- remove_proc_entry(hinfo->pde->name, parent);
+ remove_proc_entry(hinfo->name, parent);
htable_selective_cleanup(hinfo, select_all);
+ kfree(hinfo->name);
vfree(hinfo);
}
@@ -344,7 +352,7 @@ static struct xt_hashlimit_htable *htable_find_get(struct net *net,
struct xt_hashlimit_htable *hinfo;
hlist_for_each_entry(hinfo, &hashlimit_net->htables, node) {
- if (!strcmp(name, hinfo->pde->name) &&
+ if (!strcmp(name, hinfo->name) &&
hinfo->family == family) {
hinfo->use++;
return hinfo;
@@ -887,7 +895,7 @@ static void __net_exit hashlimit_proc_net_exit(struct net *net)
pde = hashlimit_net->ip6t_hashlimit;
hlist_for_each_entry(hinfo, &hashlimit_net->htables, node)
- remove_proc_entry(hinfo->pde->name, pde);
+ remove_proc_entry(hinfo->name, pde);
hashlimit_net->ipt_hashlimit = NULL;
hashlimit_net->ip6t_hashlimit = NULL;