diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2012-07-26 21:08:32 -0700 |
---|---|---|
committer | Ziyan <jaraidaniel@gmail.com> | 2016-04-03 14:55:54 +0200 |
commit | cd3e667d8bc6ec17361f9ae7cb274c0805803822 (patch) | |
tree | c35e070e437e4e0355aa469c25a2009884089ac7 /fs | |
parent | e86da70c31376c5b743373ebb0b5afc519c624be (diff) | |
download | kernel_samsung_tuna-cd3e667d8bc6ec17361f9ae7cb274c0805803822.zip kernel_samsung_tuna-cd3e667d8bc6ec17361f9ae7cb274c0805803822.tar.gz kernel_samsung_tuna-cd3e667d8bc6ec17361f9ae7cb274c0805803822.tar.bz2 |
vfs: Add a user namespace reference from struct mnt_namespace
This will allow for support for unprivileged mounts in a new user namespace.
Acked-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
(cherry picked from commit 771b1371686e0a63e938ada28de020b9a0040f55)
Diffstat (limited to 'fs')
-rw-r--r-- | fs/namespace.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index dfe3e48..3f5e356 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -22,6 +22,7 @@ #include <linux/sysfs.h> #include <linux/seq_file.h> #include <linux/mnt_namespace.h> +#include <linux/user_namespace.h> #include <linux/namei.h> #include <linux/nsproxy.h> #include <linux/security.h> @@ -2395,6 +2396,12 @@ dput_out: return retval; } +static void free_mnt_ns(struct mnt_namespace *ns) +{ + put_user_ns(ns->user_ns); + kfree(ns); +} + /* * Assign a sequence number so we can detect when we attempt to bind * mount a reference to an older mount namespace into the current @@ -2404,7 +2411,7 @@ dput_out: */ static atomic64_t mnt_ns_seq = ATOMIC64_INIT(1); -static struct mnt_namespace *alloc_mnt_ns(void) +static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) { struct mnt_namespace *new_ns; @@ -2417,6 +2424,7 @@ static struct mnt_namespace *alloc_mnt_ns(void) INIT_LIST_HEAD(&new_ns->list); init_waitqueue_head(&new_ns->poll); new_ns->event = 0; + new_ns->user_ns = get_user_ns(user_ns); return new_ns; } @@ -2425,13 +2433,13 @@ static struct mnt_namespace *alloc_mnt_ns(void) * copied from the namespace of the passed in task structure. */ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, - struct fs_struct *fs) + struct user_namespace *user_ns, struct fs_struct *fs) { struct mnt_namespace *new_ns; struct vfsmount *rootmnt = NULL, *pwdmnt = NULL; struct vfsmount *p, *q; - new_ns = alloc_mnt_ns(); + new_ns = alloc_mnt_ns(user_ns); if (IS_ERR(new_ns)) return new_ns; @@ -2441,7 +2449,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, CL_COPY_ALL | CL_EXPIRE); if (IS_ERR(new_ns->root)) { up_write(&namespace_sem); - kfree(new_ns); + free_mnt_ns(new_ns); return ERR_CAST(new_ns->root); } br_write_lock(&vfsmount_lock); @@ -2481,7 +2489,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, } struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, - struct fs_struct *new_fs) + struct user_namespace *user_ns, struct fs_struct *new_fs) { struct mnt_namespace *new_ns; @@ -2491,7 +2499,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, if (!(flags & CLONE_NEWNS)) return ns; - new_ns = dup_mnt_ns(ns, new_fs); + new_ns = dup_mnt_ns(ns, user_ns, new_fs); put_mnt_ns(ns); return new_ns; @@ -2503,9 +2511,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, */ struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt) { - struct mnt_namespace *new_ns; - - new_ns = alloc_mnt_ns(); + struct mnt_namespace *new_ns = alloc_mnt_ns(&init_user_ns); if (!IS_ERR(new_ns)) { mnt->mnt_ns = new_ns; new_ns->root = mnt; @@ -2743,7 +2749,7 @@ void put_mnt_ns(struct mnt_namespace *ns) br_write_unlock(&vfsmount_lock); up_write(&namespace_sem); release_mounts(&umount_list); - kfree(ns); + free_mnt_ns(ns); } EXPORT_SYMBOL(put_mnt_ns); |