Re: [PATCH for 2.6.33] conntrack: restrict runtime hashsize modifications

Patrick McHardy
2010-02-05T11:25:46Z

[-- Attachment #1: Type: text/plain, Size: 715 bytes --]

Patrick McHardy wrote:
> Alexey Dobriyan wrote:
>> On Fri, Feb 5, 2010 at 1:16 PM, Patrick McHardy <kaber@trash.net> wrote:
>>> OK testing looks fine, although I'm quite surprised that its actually
>>> possible to change module parameters from within non-init namespaces.
>>> How is this supposed to work at all? I don't see how sysfs could
>>> possibly provide a network namespace context ...
>>
>> You can do in write hook
>>
>> if (!net_eq(current->nsproxy->net_ns, &init_net))
>> return -EINVAL;
>
> Right, I see. So we could actually make resizing work for all
> namespaces quite easily. Is there any reason not to do this?
>

Something like this (untested) patch on top of the previous one.

[-- Attachment #2: x --]
[-- Type: text/plain, Size: 2117 bytes --]

diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index ef1c856..212dac3 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -31,6 +31,7 @@
#include <linux/socket.h>
#include <linux/mm.h>
#include <linux/rculist_nulls.h>
+#include <linux/nsproxy.h>

#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_l3proto.h>
@@ -1194,6 +1195,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
unsigned int hashsize, old_size;
struct hlist_nulls_head *hash, *old_hash;
struct nf_conntrack_tuple_hash *h;
+ struct net *net = current->nsproxy->net_ns;

/* On boot, we can set this without any fancy locking. */
if (!nf_conntrack_htable_size)
@@ -1213,9 +1215,9 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
* though since that required taking the lock.
*/
spin_lock_bh(&nf_conntrack_lock);
- for (i = 0; i < init_net.ct.htable_size; i++) {
- while (!hlist_nulls_empty(&init_net.ct.hash[i])) {
- h = hlist_nulls_entry(init_net.ct.hash[i].first,
+ for (i = 0; i < net->ct.htable_size; i++) {
+ while (!hlist_nulls_empty(&net->ct.hash[i])) {
+ h = hlist_nulls_entry(net->ct.hash[i].first,
struct nf_conntrack_tuple_hash, hnnode);
hlist_nulls_del_rcu(&h->hnnode);
bucket = __hash_conntrack(&h->tuple, hashsize,
@@ -1223,13 +1225,13 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
hlist_nulls_add_head_rcu(&h->hnnode, &hash[bucket]);
}
}
- old_size = init_net.ct.htable_size;
- old_vmalloced = init_net.ct.hash_vmalloc;
- old_hash = init_net.ct.hash;
+ old_size = net->ct.htable_size;
+ old_vmalloced = net->ct.hash_vmalloc;
+ old_hash = net->ct.hash;

- init_net.ct.htable_size = nf_conntrack_htable_size = hashsize;
- init_net.ct.hash_vmalloc = vmalloced;
- init_net.ct.hash = hash;
+ net->ct.htable_size = nf_conntrack_htable_size = hashsize;
+ net->ct.hash_vmalloc = vmalloced;
+ net->ct.hash = hash;
spin_unlock_bh(&nf_conntrack_lock);

nf_ct_free_hashtable(old_hash, old_vmalloced, old_size);