pidns: Add setns support

- Pid namespaces are designed to be inescapable so verify that the
  passed in pid namespace is a child of the currently active
  pid namespace or the currently active pid namespace itself.

  Allowing the currently active pid namespace is important so
  the effects of an earlier setns can be cancelled.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
此提交包含在:
Eric W. Biederman
2010-03-07 18:17:03 -08:00
父節點 225778d68d
當前提交 57e8391d32
共有 3 個檔案被更改,包括 58 行新增0 行删除

查看文件

@@ -301,6 +301,60 @@ int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd)
return 0;
}
static void *pidns_get(struct task_struct *task)
{
struct pid_namespace *ns;
rcu_read_lock();
ns = get_pid_ns(task_active_pid_ns(task));
rcu_read_unlock();
return ns;
}
static void pidns_put(void *ns)
{
put_pid_ns(ns);
}
static int pidns_install(struct nsproxy *nsproxy, void *ns)
{
struct pid_namespace *active = task_active_pid_ns(current);
struct pid_namespace *ancestor, *new = ns;
if (!ns_capable(new->user_ns, CAP_SYS_ADMIN))
return -EPERM;
/*
* Only allow entering the current active pid namespace
* or a child of the current active pid namespace.
*
* This is required for fork to return a usable pid value and
* this maintains the property that processes and their
* children can not escape their current pid namespace.
*/
if (new->level < active->level)
return -EINVAL;
ancestor = new;
while (ancestor->level > active->level)
ancestor = ancestor->parent;
if (ancestor != active)
return -EINVAL;
put_pid_ns(nsproxy->pid_ns);
nsproxy->pid_ns = get_pid_ns(new);
return 0;
}
const struct proc_ns_operations pidns_operations = {
.name = "pid",
.type = CLONE_NEWPID,
.get = pidns_get,
.put = pidns_put,
.install = pidns_install,
};
static __init int pid_namespaces_init(void)
{
pid_ns_cachep = KMEM_CACHE(pid_namespace, SLAB_PANIC);