Release 4.15 kernel/nsproxy.c
/*
* Copyright (C) 2006 IBM Corporation
*
* Author: Serge Hallyn <serue@us.ibm.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*
* Jun 2006 - namespaces support
* OpenVZ, SWsoft Inc.
* Pavel Emelianov <xemul@openvz.org>
*/
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/nsproxy.h>
#include <linux/init_task.h>
#include <linux/mnt_namespace.h>
#include <linux/utsname.h>
#include <linux/pid_namespace.h>
#include <net/net_namespace.h>
#include <linux/ipc_namespace.h>
#include <linux/proc_ns.h>
#include <linux/file.h>
#include <linux/syscalls.h>
#include <linux/cgroup.h>
#include <linux/perf_event.h>
static struct kmem_cache *nsproxy_cachep;
struct nsproxy init_nsproxy = {
.count = ATOMIC_INIT(1),
.uts_ns = &init_uts_ns,
#if defined(CONFIG_POSIX_MQUEUE) || defined(CONFIG_SYSVIPC)
.ipc_ns = &init_ipc_ns,
#endif
.mnt_ns = NULL,
.pid_ns_for_children = &init_pid_ns,
#ifdef CONFIG_NET
.net_ns = &init_net,
#endif
#ifdef CONFIG_CGROUPS
.cgroup_ns = &init_cgroup_ns,
#endif
};
static inline struct nsproxy *create_nsproxy(void)
{
struct nsproxy *nsproxy;
nsproxy = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL);
if (nsproxy)
atomic_set(&nsproxy->count, 1);
return nsproxy;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Serge E. Hallyn | 26 | 61.90% | 1 | 33.33% |
Cédric Le Goater | 9 | 21.43% | 1 | 33.33% |
Alexey Dobriyan | 7 | 16.67% | 1 | 33.33% |
Total | 42 | 100.00% | 3 | 100.00% |
/*
* Create new nsproxy and all of its the associated namespaces.
* Return the newly created nsproxy. Do not attach this to the task,
* leave it to the caller to do proper locking and attach it to task.
*/
static struct nsproxy *create_new_namespaces(unsigned long flags,
struct task_struct *tsk, struct user_namespace *user_ns,
struct fs_struct *new_fs)
{
struct nsproxy *new_nsp;
int err;
new_nsp = create_nsproxy();
if (!new_nsp)
return ERR_PTR(-ENOMEM);
new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, user_ns, new_fs);
if (IS_ERR(new_nsp->mnt_ns)) {
err = PTR_ERR(new_nsp->mnt_ns);
goto out_ns;
}
new_nsp->uts_ns = copy_utsname(flags, user_ns, tsk->nsproxy->uts_ns);
if (IS_ERR(new_nsp->uts_ns)) {
err = PTR_ERR(new_nsp->uts_ns);
goto out_uts;
}
new_nsp->ipc_ns = copy_ipcs(flags, user_ns, tsk->nsproxy->ipc_ns);
if (IS_ERR(new_nsp->ipc_ns)) {
err = PTR_ERR(new_nsp->ipc_ns);
goto out_ipc;
}
new_nsp->pid_ns_for_children =
copy_pid_ns(flags, user_ns, tsk->nsproxy->pid_ns_for_children);
if (IS_ERR(new_nsp->pid_ns_for_children)) {
err = PTR_ERR(new_nsp->pid_ns_for_children);
goto out_pid;
}
new_nsp->cgroup_ns = copy_cgroup_ns(flags, user_ns,
tsk->nsproxy->cgroup_ns);
if (IS_ERR(new_nsp->cgroup_ns)) {
err = PTR_ERR(new_nsp->cgroup_ns);
goto out_cgroup;
}
new_nsp->net_ns = copy_net_ns(flags, user_ns, tsk->nsproxy->net_ns);
if (IS_ERR(new_nsp->net_ns)) {
err = PTR_ERR(new_nsp->net_ns);
goto out_net;
}
return new_nsp;
out_net:
put_cgroup_ns(new_nsp->cgroup_ns);
out_cgroup:
if (new_nsp->pid_ns_for_children)
put_pid_ns(new_nsp->pid_ns_for_children);
out_pid:
if (new_nsp->ipc_ns)
put_ipc_ns(new_nsp->ipc_ns);
out_ipc:
if (new_nsp->uts_ns)
put_uts_ns(new_nsp->uts_ns);
out_uts:
if (new_nsp->mnt_ns)
put_mnt_ns(new_nsp->mnt_ns);
out_ns:
kmem_cache_free(nsproxy_cachep, new_nsp);
return ERR_PTR(err);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Badari Pulavarty | 146 | 38.32% | 1 | 5.00% |
Eric W. Biedermann | 70 | 18.37% | 7 | 35.00% |
Cédric Le Goater | 67 | 17.59% | 4 | 20.00% |
Aditya Kali | 49 | 12.86% | 1 | 5.00% |
Serge E. Hallyn | 32 | 8.40% | 3 | 15.00% |
Kirill Korotaev | 9 | 2.36% | 2 | 10.00% |
Andrew Lutomirski | 6 | 1.57% | 1 | 5.00% |
Alexey Dobriyan | 2 | 0.52% | 1 | 5.00% |
Total | 381 | 100.00% | 20 | 100.00% |
/*
* called from clone. This now handles copy for nsproxy and all
* namespaces therein.
*/
int copy_namespaces(unsigned long flags, struct task_struct *tsk)
{
struct nsproxy *old_ns = tsk->nsproxy;
struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns);
struct nsproxy *new_ns;
if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
CLONE_NEWPID | CLONE_NEWNET |
CLONE_NEWCGROUP)))) {
get_nsproxy(old_ns);
return 0;
}
if (!ns_capable(user_ns, CAP_SYS_ADMIN))
return -EPERM;
/*
* CLONE_NEWIPC must detach from the undolist: after switching
* to a new ipc namespace, the semaphore arrays from the old
* namespace are unreachable. In clone parlance, CLONE_SYSVSEM
* means share undolist with parent, so we must forbid using
* it along with CLONE_NEWIPC.
*/
if ((flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) ==
(CLONE_NEWIPC | CLONE_SYSVSEM))
return -EINVAL;
new_ns = create_new_namespaces(flags, tsk, user_ns, tsk->fs);
if (IS_ERR(new_ns))
return PTR_ERR(new_ns);
tsk->nsproxy = new_ns;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Serge E. Hallyn | 75 | 50.68% | 6 | 35.29% |
Eric W. Biedermann | 36 | 24.32% | 5 | 29.41% |
Badari Pulavarty | 17 | 11.49% | 1 | 5.88% |
Kirill Korotaev | 8 | 5.41% | 1 | 5.88% |
Raphael S. Carvalho | 6 | 4.05% | 1 | 5.88% |
Pavel Emelyanov | 2 | 1.35% | 1 | 5.88% |
Cédric Le Goater | 2 | 1.35% | 1 | 5.88% |
Aditya Kali | 2 | 1.35% | 1 | 5.88% |
Total | 148 | 100.00% | 17 | 100.00% |
void free_nsproxy(struct nsproxy *ns)
{
if (ns->mnt_ns)
put_mnt_ns(ns->mnt_ns);
if (ns->uts_ns)
put_uts_ns(ns->uts_ns);
if (ns->ipc_ns)
put_ipc_ns(ns->ipc_ns);
if (ns->pid_ns_for_children)
put_pid_ns(ns->pid_ns_for_children);
put_cgroup_ns(ns->cgroup_ns);
put_net(ns->net_ns);
kmem_cache_free(nsproxy_cachep, ns);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Serge E. Hallyn | 37 | 44.58% | 3 | 30.00% |
Kirill Korotaev | 16 | 19.28% | 2 | 20.00% |
Cédric Le Goater | 14 | 16.87% | 2 | 20.00% |
Eric W. Biedermann | 7 | 8.43% | 1 | 10.00% |
Aditya Kali | 7 | 8.43% | 1 | 10.00% |
Andrew Lutomirski | 2 | 2.41% | 1 | 10.00% |
Total | 83 | 100.00% | 10 | 100.00% |
/*
* Called from unshare. Unshare all the namespaces part of nsproxy.
* On success, returns the new nsproxy.
*/
int unshare_nsproxy_namespaces(unsigned long unshare_flags,
struct nsproxy **new_nsp, struct cred *new_cred, struct fs_struct *new_fs)
{
struct user_namespace *user_ns;
int err = 0;
if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
CLONE_NEWNET | CLONE_NEWPID | CLONE_NEWCGROUP)))
return 0;
user_ns = new_cred ? new_cred->user_ns : current_user_ns();
if (!ns_capable(user_ns, CAP_SYS_ADMIN))
return -EPERM;
*new_nsp = create_new_namespaces(unshare_flags, current, user_ns,
new_fs ? new_fs : current->fs);
if (IS_ERR(*new_nsp)) {
err = PTR_ERR(*new_nsp);
goto out;
}
out:
return err;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Badari Pulavarty | 91 | 70.00% | 1 | 12.50% |
Eric W. Biedermann | 29 | 22.31% | 4 | 50.00% |
Serge E. Hallyn | 8 | 6.15% | 2 | 25.00% |
Aditya Kali | 2 | 1.54% | 1 | 12.50% |
Total | 130 | 100.00% | 8 | 100.00% |
void switch_task_namespaces(struct task_struct *p, struct nsproxy *new)
{
struct nsproxy *ns;
might_sleep();
task_lock(p);
ns = p->nsproxy;
p->nsproxy = new;
task_unlock(p);
if (ns && atomic_dec_and_test(&ns->count))
free_nsproxy(ns);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pavel Emelyanov | 52 | 83.87% | 1 | 50.00% |
Eric W. Biedermann | 10 | 16.13% | 1 | 50.00% |
Total | 62 | 100.00% | 2 | 100.00% |
void exit_task_namespaces(struct task_struct *p)
{
switch_task_namespaces(p, NULL);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pavel Emelyanov | 17 | 100.00% | 1 | 100.00% |
Total | 17 | 100.00% | 1 | 100.00% |
SYSCALL_DEFINE2(setns, int, fd, int, nstype)
{
struct task_struct *tsk = current;
struct nsproxy *new_nsproxy;
struct file *file;
struct ns_common *ns;
int err;
file = proc_ns_fget(fd);
if (IS_ERR(file))
return PTR_ERR(file);
err = -EINVAL;
ns = get_proc_ns(file_inode(file));
if (nstype && (ns->ops->type != nstype))
goto out;
new_nsproxy = create_new_namespaces(0, tsk, current_user_ns(), tsk->fs);
if (IS_ERR(new_nsproxy)) {
err = PTR_ERR(new_nsproxy);
goto out;
}
err = ns->ops->install(new_nsproxy, ns);
if (err) {
free_nsproxy(new_nsproxy);
goto out;
}
switch_task_namespaces(tsk, new_nsproxy);
perf_event_namespaces(tsk);
out:
fput(file);
return err;
}
int __init nsproxy_cache_init(void)
{
nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Cédric Le Goater | 19 | 95.00% | 1 | 50.00% |
Pavel Emelyanov | 1 | 5.00% | 1 | 50.00% |
Total | 20 | 100.00% | 2 | 100.00% |
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Eric W. Biedermann | 319 | 26.97% | 13 | 28.89% |
Badari Pulavarty | 255 | 21.56% | 1 | 2.22% |
Serge E. Hallyn | 199 | 16.82% | 8 | 17.78% |
Cédric Le Goater | 121 | 10.23% | 5 | 11.11% |
Pavel Emelyanov | 75 | 6.34% | 4 | 8.89% |
Aditya Kali | 74 | 6.26% | 1 | 2.22% |
Alexey Dobriyan | 63 | 5.33% | 2 | 4.44% |
Kirill Korotaev | 35 | 2.96% | 2 | 4.44% |
Al Viro | 13 | 1.10% | 3 | 6.67% |
Andrew Lutomirski | 9 | 0.76% | 1 | 2.22% |
Hari Bathini | 8 | 0.68% | 1 | 2.22% |
Raphael S. Carvalho | 6 | 0.51% | 1 | 2.22% |
Tejun Heo | 3 | 0.25% | 1 | 2.22% |
David Howells | 2 | 0.17% | 1 | 2.22% |
Paul Gortmaker | 1 | 0.08% | 1 | 2.22% |
Total | 1183 | 100.00% | 45 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.