pid: Implement ns_of_pid
Subsystems (3)
PATCH v2 1/2 pid: Implement ns_of_pid
Resending patch with correct "From", "Signed-off-by" and a note in function header of ns_of_pid().
---
From: Eric Biederman <[email protected]>
Subject: [PATCH] pid: Implement ns_of_pid
A current problem with the pid namespace is that it is easy to do pid related work after exit_task_namespaces which drops the nsproxy pointer.
However if we are doing pid namespace related work we are always operating on some struct pid which retains the pid_namespace pointer of the pid namespace it was allocated in.
So provide ns_of_pid which allows us to find the pid namespace a pid was allocated in.
Using this we have the needed infrastructure to do pid namespace related work at anytime we have a struct pid, removing the chance of accidentally having a NULL pointer dereference when accessing current->nsproxy.
Changelog[v2]:
- Add a note in function header of ns_of_pid() re: NULL pid.
--- include/linux/pid.h | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)
include/linux/pid.h +18 -0
@@ -122,6 +122,24 @@ int next_pidmap(struct pid_namespace *pid_ns, int last);extern struct pid *alloc_pid (struct pid_namespace *ns);extern void free_pid (struct pid *pid); +/* +* ns_of_pid() returns the pid namespace in which the specified pid was +* allocated. +* +* NOTE: +* ns_of_pid() is expected to be called for a process (task) that has +* an attached 'struct pid' (see attach_pid(), detach_pid()) i.e @pid +* is expected to be non-NULL. If @pid is NULL, caller should handle +* the resulting NULL pid-ns. +*/ +static inline struct pid_namespace *ns_of_pid (struct pid *pid) +{ +struct pid_namespace *ns =NULL ; +if (pid) + ns = pid->numbers[pid->level].ns; +return ns; +} +/* * the helpers to get the pid's id seen from different namespaces *
Signature · 1 line
1.5.2.5
PATCH 2/2 pid: generalize task_active_pid_ns
Resending patch with correct "From", "Signed-off-by".
---
From: Eric Biederman <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
Date: Fri, 12 Dec 2008 11:49:27 -0800
Subject: [PATCH] pid: Generalize task_active_pid_ns
Currently task_active_pid_ns is not safe to call after a task becomes a zombie and exit_task_namespaces is called, as nsproxy becomes NULL. By reading the pid namespace from the pid of the task we can trivially solve this problem at the cost of one extra memory read in what should be the same cacheline as we read the namespace from.
When moving things around I have made task_active_pid_ns out of line because keeping it in pid_namespace.h would require adding includes of pid.h and sched.h that I don't think we want.
This change does make task_active_pid_ns unsafe to call during copy_process until we attach a pid on the task_struct which seems to be a reasonable trade off.
--- include/linux/pid_namespace.h | 6 +----- kernel/fork.c | 4 ++-- kernel/pid.c | 6 ++++++ 3 files changed, 9 insertions(+), 7 deletions(-)
include/linux/pid_namespace.h +1 -5
@@ -79,11 +79,7 @@ static inline void zap_pid_ns_processes(struct pid_namespace *ns) }#endif /* CONFIG_PID_NS */ -static inline struct pid_namespace *task_active_pid_ns (struct task_struct *tsk) -{ -return tsk->nsproxy->pid_ns; -} - +extern struct pid_namespace *task_active_pid_ns (struct task_struct *tsk);void pidhash_init (void );void pidmap_init (void );
kernel/fork.c +2 -2
@@ -1100,12 +1100,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,if (pid != &init_struct_pid) { retval = -ENOMEM ; - pid =alloc_pid (task_active_pid_ns (p)); + pid =alloc_pid (p->nsproxy->pid_ns);if (!pid) goto bad_fork_cleanup_io;if (clone_flags &CLONE_NEWPID ) { - retval =pid_ns_prepare_proc (task_active_pid_ns (p)); + retval =pid_ns_prepare_proc (p->nsproxy->pid_ns);if (retval <0 ) goto bad_fork_free_pid; }
kernel/pid.c +6 -0
@@ -474,6 +474,12 @@ pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) }EXPORT_SYMBOL (task_session_nr_ns); +struct pid_namespace *task_active_pid_ns (struct task_struct *tsk) +{ +return ns_of_pid (task_pid (tsk)); +} +EXPORT_SYMBOL_GPL (task_active_pid_ns); +/* * Used by proc to find the first pid that is greater then or equal to nr. *
Signature · 1 line
1.5.2.5