On Wed, 2011-05-11 at 14:34 -0700, Eric W. Biederman wrote:
Nathan Lynch [off-list ref] writes:
quoted
On Fri, 2011-05-06 at 19:24 -0700, Eric W. Biederman wrote:
quoted
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 3f86026..bf7707e 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -573,3 +573,34 @@ void unregister_pernet_device(struct pernet_operations *ops)
mutex_unlock(&net_mutex);
}
EXPORT_SYMBOL_GPL(unregister_pernet_device);
+
+#ifdef CONFIG_NET_NS
+static void *netns_get(struct task_struct *task)
+{
+ struct net *net;
+ rcu_read_lock();
+ net = get_net(task->nsproxy->net_ns);
This should use task_nsproxy() and check the result before grabbing the
net_ns, but I think you fix that in a later patch.
Regardless, it looks as if all the proc_ns_ops->get() implementations
really just want the nsproxy, so maybe the get() methods should take
that instead of the task_struct, and proc_ns_instantiate() should do
something like:
struct nsproxy *nsproxy;
...
ei->ns_ops = ns_ops;
error = -ESRCH;
rcu_read_lock();
nsproxy = task_nsproxy(task);
rcu_read_unlock();
if (!nsproxy)
got out;
ei->ns = ns_ops->get(nsproxy);
So then the zombie check is consolidated in one place instead of having
to do it in every get() method.
For the pid namespace at least I want the task not the nsproxy,
so I can use task_active_pid_namespace().
I admit that is a little asymmetrical with the install, but at
least until the details of getting the pid namespace working in
this context are worked out I don't want to reconsider the
current design.
There is also the user namespace that does not even exist in
nsproxy to consider. I will worry about that namespace when
it happens.
Ultimately nsproxy is an space/time optimization that not all
namespaces use so forcing it in the design is probably not
what we want.
Okay.
quoted
quoted
+ rcu_read_unlock();
+ return net;
+}
+
+static void netns_put(void *ns)
+{
+ put_net(ns);
+}
+
+static int netns_install(struct nsproxy *nsproxy, void *ns)
+{
+ put_net(nsproxy->net_ns);
+ nsproxy->net_ns = get_net(ns);
+ return 0;
+}
This introduces a window where, potentially, nsproxy->net_ns is stale
before it is updated with the namespace which is being attached, no?
(Same concern applies to other install methods in the patch set). It
seems possible to oops the kernel in this window by looking up
/proc/$PID/ns/net while $PID is in the midst of setns().
Except the nsproxy being referred to is a brand new nsproxy, with an
extra reference count on every namespace. current->nsproxy still
contains the reference counts of the current process.
Ahh, yeah. Got it. Thanks.