diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-25 21:10:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-25 21:10:16 -0400 |
commit | 14d74e0cab7a7779a7ff0c3863c04c8a8e507106 (patch) | |
tree | 5e27d7495f8f7ce178b637d588ec42bd7b4173d8 /kernel | |
parent | 49a78d085fa6b44d6ed791923c7172a6433589c2 (diff) | |
parent | 956c920786694f51601a0ef7ee12956fd6aa216e (diff) |
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.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/nsproxy.c | 42 | ||||
-rw-r--r-- | kernel/utsname.c | 39 |
2 files changed, 81 insertions, 0 deletions
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index a05d191ffdd9..5424e37673ed 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c | |||
@@ -22,6 +22,9 @@ | |||
22 | #include <linux/pid_namespace.h> | 22 | #include <linux/pid_namespace.h> |
23 | #include <net/net_namespace.h> | 23 | #include <net/net_namespace.h> |
24 | #include <linux/ipc_namespace.h> | 24 | #include <linux/ipc_namespace.h> |
25 | #include <linux/proc_fs.h> | ||
26 | #include <linux/file.h> | ||
27 | #include <linux/syscalls.h> | ||
25 | 28 | ||
26 | static struct kmem_cache *nsproxy_cachep; | 29 | static struct kmem_cache *nsproxy_cachep; |
27 | 30 | ||
@@ -233,6 +236,45 @@ void exit_task_namespaces(struct task_struct *p) | |||
233 | switch_task_namespaces(p, NULL); | 236 | switch_task_namespaces(p, NULL); |
234 | } | 237 | } |
235 | 238 | ||
239 | SYSCALL_DEFINE2(setns, int, fd, int, nstype) | ||
240 | { | ||
241 | const struct proc_ns_operations *ops; | ||
242 | struct task_struct *tsk = current; | ||
243 | struct nsproxy *new_nsproxy; | ||
244 | struct proc_inode *ei; | ||
245 | struct file *file; | ||
246 | int err; | ||
247 | |||
248 | if (!capable(CAP_SYS_ADMIN)) | ||
249 | return -EPERM; | ||
250 | |||
251 | file = proc_ns_fget(fd); | ||
252 | if (IS_ERR(file)) | ||
253 | return PTR_ERR(file); | ||
254 | |||
255 | err = -EINVAL; | ||
256 | ei = PROC_I(file->f_dentry->d_inode); | ||
257 | ops = ei->ns_ops; | ||
258 | if (nstype && (ops->type != nstype)) | ||
259 | goto out; | ||
260 | |||
261 | new_nsproxy = create_new_namespaces(0, tsk, tsk->fs); | ||
262 | if (IS_ERR(new_nsproxy)) { | ||
263 | err = PTR_ERR(new_nsproxy); | ||
264 | goto out; | ||
265 | } | ||
266 | |||
267 | err = ops->install(new_nsproxy, ei->ns); | ||
268 | if (err) { | ||
269 | free_nsproxy(new_nsproxy); | ||
270 | goto out; | ||
271 | } | ||
272 | switch_task_namespaces(tsk, new_nsproxy); | ||
273 | out: | ||
274 | fput(file); | ||
275 | return err; | ||
276 | } | ||
277 | |||
236 | static int __init nsproxy_cache_init(void) | 278 | static int __init nsproxy_cache_init(void) |
237 | { | 279 | { |
238 | nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC); | 280 | nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC); |
diff --git a/kernel/utsname.c b/kernel/utsname.c index 44646179eaba..bff131b9510a 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/user_namespace.h> | 17 | #include <linux/user_namespace.h> |
18 | #include <linux/proc_fs.h> | ||
18 | 19 | ||
19 | static struct uts_namespace *create_uts_ns(void) | 20 | static struct uts_namespace *create_uts_ns(void) |
20 | { | 21 | { |
@@ -79,3 +80,41 @@ void free_uts_ns(struct kref *kref) | |||
79 | put_user_ns(ns->user_ns); | 80 | put_user_ns(ns->user_ns); |
80 | kfree(ns); | 81 | kfree(ns); |
81 | } | 82 | } |
83 | |||
84 | static void *utsns_get(struct task_struct *task) | ||
85 | { | ||
86 | struct uts_namespace *ns = NULL; | ||
87 | struct nsproxy *nsproxy; | ||
88 | |||
89 | rcu_read_lock(); | ||
90 | nsproxy = task_nsproxy(task); | ||
91 | if (nsproxy) { | ||
92 | ns = nsproxy->uts_ns; | ||
93 | get_uts_ns(ns); | ||
94 | } | ||
95 | rcu_read_unlock(); | ||
96 | |||
97 | return ns; | ||
98 | } | ||
99 | |||
100 | static void utsns_put(void *ns) | ||
101 | { | ||
102 | put_uts_ns(ns); | ||
103 | } | ||
104 | |||
105 | static int utsns_install(struct nsproxy *nsproxy, void *ns) | ||
106 | { | ||
107 | get_uts_ns(ns); | ||
108 | put_uts_ns(nsproxy->uts_ns); | ||
109 | nsproxy->uts_ns = ns; | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | const struct proc_ns_operations utsns_operations = { | ||
114 | .name = "uts", | ||
115 | .type = CLONE_NEWUTS, | ||
116 | .get = utsns_get, | ||
117 | .put = utsns_put, | ||
118 | .install = utsns_install, | ||
119 | }; | ||
120 | |||