diff options
Diffstat (limited to 'kernel/user_namespace.c')
-rw-r--r-- | kernel/user_namespace.c | 25 |
1 files changed, 25 insertions, 0 deletions
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) |