diff options
Diffstat (limited to 'kernel/nsproxy.c')
-rw-r--r-- | kernel/nsproxy.c | 42 |
1 files changed, 42 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); |