aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cgroup.c6
-rw-r--r--kernel/pid_namespace.c25
-rw-r--r--kernel/user_namespace.c25
-rw-r--r--kernel/utsname.c6
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
6424static struct user_namespace *cgroupns_owner(struct ns_common *ns)
6425{
6426 return to_cg_ns(ns)->user_ns;
6427}
6428
6424const struct proc_ns_operations cgroupns_operations = { 6429const 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
6432static __init int cgroup_namespaces_init(void) 6438static __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
408static 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
426static struct user_namespace *pidns_owner(struct ns_common *ns)
427{
428 return to_pid_ns(ns)->user_ns;
429}
430
408const struct proc_ns_operations pidns_operations = { 431const 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
416static __init int pid_namespaces_init(void) 441static __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
1053struct 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
1071static struct user_namespace *userns_owner(struct ns_common *ns)
1072{
1073 return to_user_ns(ns)->parent;
1074}
1075
1053const struct proc_ns_operations userns_operations = { 1076const 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
1061static __init int user_namespaces_init(void) 1086static __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
157static struct user_namespace *utsns_owner(struct ns_common *ns)
158{
159 return to_uts_ns(ns)->user_ns;
160}
161
157const struct proc_ns_operations utsns_operations = { 162const 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};