Merge git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/linux-2.6-nsfd
* git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/linux-2.6-nsfd: net: fix get_net_ns_by_fd for !CONFIG_NET_NS ns proc: Return -ENOENT for a nonexistent /proc/self/ns/ entry. ns: Declare sys_setns in syscalls.h net: Allow setting the network namespace by fd ns proc: Add support for the ipc namespace ns proc: Add support for the uts namespace ns proc: Add support for the network namespace. ns: Introduce the setns syscall ns: proc files for namespace naming policy.
This commit is contained in:
@@ -22,6 +22,9 @@
|
||||
#include <linux/pid_namespace.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <linux/ipc_namespace.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/syscalls.h>
|
||||
|
||||
static struct kmem_cache *nsproxy_cachep;
|
||||
|
||||
@@ -233,6 +236,45 @@ void exit_task_namespaces(struct task_struct *p)
|
||||
switch_task_namespaces(p, NULL);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE2(setns, int, fd, int, nstype)
|
||||
{
|
||||
const struct proc_ns_operations *ops;
|
||||
struct task_struct *tsk = current;
|
||||
struct nsproxy *new_nsproxy;
|
||||
struct proc_inode *ei;
|
||||
struct file *file;
|
||||
int err;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
file = proc_ns_fget(fd);
|
||||
if (IS_ERR(file))
|
||||
return PTR_ERR(file);
|
||||
|
||||
err = -EINVAL;
|
||||
ei = PROC_I(file->f_dentry->d_inode);
|
||||
ops = ei->ns_ops;
|
||||
if (nstype && (ops->type != nstype))
|
||||
goto out;
|
||||
|
||||
new_nsproxy = create_new_namespaces(0, tsk, tsk->fs);
|
||||
if (IS_ERR(new_nsproxy)) {
|
||||
err = PTR_ERR(new_nsproxy);
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = ops->install(new_nsproxy, ei->ns);
|
||||
if (err) {
|
||||
free_nsproxy(new_nsproxy);
|
||||
goto out;
|
||||
}
|
||||
switch_task_namespaces(tsk, new_nsproxy);
|
||||
out:
|
||||
fput(file);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __init nsproxy_cache_init(void)
|
||||
{
|
||||
nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/user_namespace.h>
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
static struct uts_namespace *create_uts_ns(void)
|
||||
{
|
||||
@@ -79,3 +80,41 @@ void free_uts_ns(struct kref *kref)
|
||||
put_user_ns(ns->user_ns);
|
||||
kfree(ns);
|
||||
}
|
||||
|
||||
static void *utsns_get(struct task_struct *task)
|
||||
{
|
||||
struct uts_namespace *ns = NULL;
|
||||
struct nsproxy *nsproxy;
|
||||
|
||||
rcu_read_lock();
|
||||
nsproxy = task_nsproxy(task);
|
||||
if (nsproxy) {
|
||||
ns = nsproxy->uts_ns;
|
||||
get_uts_ns(ns);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return ns;
|
||||
}
|
||||
|
||||
static void utsns_put(void *ns)
|
||||
{
|
||||
put_uts_ns(ns);
|
||||
}
|
||||
|
||||
static int utsns_install(struct nsproxy *nsproxy, void *ns)
|
||||
{
|
||||
get_uts_ns(ns);
|
||||
put_uts_ns(nsproxy->uts_ns);
|
||||
nsproxy->uts_ns = ns;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct proc_ns_operations utsns_operations = {
|
||||
.name = "uts",
|
||||
.type = CLONE_NEWUTS,
|
||||
.get = utsns_get,
|
||||
.put = utsns_put,
|
||||
.install = utsns_install,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user