diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/cgroup.c | 6 | ||||
-rw-r--r-- | kernel/pid_namespace.c | 25 | ||||
-rw-r--r-- | kernel/user_namespace.c | 25 | ||||
-rw-r--r-- | kernel/utsname.c | 6 |
4 files changed, 62 insertions, 0 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index f1dd4b076210..d6504338e284 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -6421,12 +6421,18 @@ static void cgroupns_put(struct ns_common *ns) | |||
6421 | put_cgroup_ns(to_cg_ns(ns)); | 6421 | put_cgroup_ns(to_cg_ns(ns)); |
6422 | } | 6422 | } |
6423 | 6423 | ||
6424 | static struct user_namespace *cgroupns_owner(struct ns_common *ns) | ||
6425 | { | ||
6426 | return to_cg_ns(ns)->user_ns; | ||
6427 | } | ||
6428 | |||
6424 | const struct proc_ns_operations cgroupns_operations = { | 6429 | const struct proc_ns_operations cgroupns_operations = { |
6425 | .name = "cgroup", | 6430 | .name = "cgroup", |
6426 | .type = CLONE_NEWCGROUP, | 6431 | .type = CLONE_NEWCGROUP, |
6427 | .get = cgroupns_get, | 6432 | .get = cgroupns_get, |
6428 | .put = cgroupns_put, | 6433 | .put = cgroupns_put, |
6429 | .install = cgroupns_install, | 6434 | .install = cgroupns_install, |
6435 | .owner = cgroupns_owner, | ||
6430 | }; | 6436 | }; |
6431 | 6437 | ||
6432 | static __init int cgroup_namespaces_init(void) | 6438 | static __init int cgroup_namespaces_init(void) |
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) |
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index f2c5ba5505f1..86b7854fec8e 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c | |||
@@ -1050,12 +1050,37 @@ static int userns_install(struct nsproxy *nsproxy, struct ns_common *ns) | |||
1050 | return commit_creds(cred); | 1050 | return commit_creds(cred); |
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | struct ns_common *ns_get_owner(struct ns_common *ns) | ||
1054 | { | ||
1055 | struct user_namespace *my_user_ns = current_user_ns(); | ||
1056 | struct user_namespace *owner, *p; | ||
1057 | |||
1058 | /* See if the owner is in the current user namespace */ | ||
1059 | owner = p = ns->ops->owner(ns); | ||
1060 | for (;;) { | ||
1061 | if (!p) | ||
1062 | return ERR_PTR(-EPERM); | ||
1063 | if (p == my_user_ns) | ||
1064 | break; | ||
1065 | p = p->parent; | ||
1066 | } | ||
1067 | |||
1068 | return &get_user_ns(owner)->ns; | ||
1069 | } | ||
1070 | |||
1071 | static struct user_namespace *userns_owner(struct ns_common *ns) | ||
1072 | { | ||
1073 | return to_user_ns(ns)->parent; | ||
1074 | } | ||
1075 | |||
1053 | const struct proc_ns_operations userns_operations = { | 1076 | const struct proc_ns_operations userns_operations = { |
1054 | .name = "user", | 1077 | .name = "user", |
1055 | .type = CLONE_NEWUSER, | 1078 | .type = CLONE_NEWUSER, |
1056 | .get = userns_get, | 1079 | .get = userns_get, |
1057 | .put = userns_put, | 1080 | .put = userns_put, |
1058 | .install = userns_install, | 1081 | .install = userns_install, |
1082 | .owner = userns_owner, | ||
1083 | .get_parent = ns_get_owner, | ||
1059 | }; | 1084 | }; |
1060 | 1085 | ||
1061 | static __init int user_namespaces_init(void) | 1086 | static __init int user_namespaces_init(void) |
diff --git a/kernel/utsname.c b/kernel/utsname.c index 35587b76faa3..6976cd47dcf6 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c | |||
@@ -154,10 +154,16 @@ static int utsns_install(struct nsproxy *nsproxy, struct ns_common *new) | |||
154 | return 0; | 154 | return 0; |
155 | } | 155 | } |
156 | 156 | ||
157 | static struct user_namespace *utsns_owner(struct ns_common *ns) | ||
158 | { | ||
159 | return to_uts_ns(ns)->user_ns; | ||
160 | } | ||
161 | |||
157 | const struct proc_ns_operations utsns_operations = { | 162 | const struct proc_ns_operations utsns_operations = { |
158 | .name = "uts", | 163 | .name = "uts", |
159 | .type = CLONE_NEWUTS, | 164 | .type = CLONE_NEWUTS, |
160 | .get = utsns_get, | 165 | .get = utsns_get, |
161 | .put = utsns_put, | 166 | .put = utsns_put, |
162 | .install = utsns_install, | 167 | .install = utsns_install, |
168 | .owner = utsns_owner, | ||
163 | }; | 169 | }; |