diff options
Diffstat (limited to 'kernel/pid_namespace.c')
-rw-r--r-- | kernel/pid_namespace.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 7542b28cc929..df9e8e9e0be7 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c | |||
@@ -405,12 +405,37 @@ static int pidns_install(struct nsproxy *nsproxy, struct ns_common *ns) | |||
405 | return 0; | 405 | return 0; |
406 | } | 406 | } |
407 | 407 | ||
408 | static struct ns_common *pidns_get_parent(struct ns_common *ns) | ||
409 | { | ||
410 | struct pid_namespace *active = task_active_pid_ns(current); | ||
411 | struct pid_namespace *pid_ns, *p; | ||
412 | |||
413 | /* See if the parent is in the current namespace */ | ||
414 | pid_ns = p = to_pid_ns(ns)->parent; | ||
415 | for (;;) { | ||
416 | if (!p) | ||
417 | return ERR_PTR(-EPERM); | ||
418 | if (p == active) | ||
419 | break; | ||
420 | p = p->parent; | ||
421 | } | ||
422 | |||
423 | return &get_pid_ns(pid_ns)->ns; | ||
424 | } | ||
425 | |||
426 | static struct user_namespace *pidns_owner(struct ns_common *ns) | ||
427 | { | ||
428 | return to_pid_ns(ns)->user_ns; | ||
429 | } | ||
430 | |||
408 | const struct proc_ns_operations pidns_operations = { | 431 | const struct proc_ns_operations pidns_operations = { |
409 | .name = "pid", | 432 | .name = "pid", |
410 | .type = CLONE_NEWPID, | 433 | .type = CLONE_NEWPID, |
411 | .get = pidns_get, | 434 | .get = pidns_get, |
412 | .put = pidns_put, | 435 | .put = pidns_put, |
413 | .install = pidns_install, | 436 | .install = pidns_install, |
437 | .owner = pidns_owner, | ||
438 | .get_parent = pidns_get_parent, | ||
414 | }; | 439 | }; |
415 | 440 | ||
416 | static __init int pid_namespaces_init(void) | 441 | static __init int pid_namespaces_init(void) |