aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-07-26 21:08:32 -0700
committerZiyan <jaraidaniel@gmail.com>2016-04-03 14:55:54 +0200
commitcd3e667d8bc6ec17361f9ae7cb274c0805803822 (patch)
treec35e070e437e4e0355aa469c25a2009884089ac7 /fs
parente86da70c31376c5b743373ebb0b5afc519c624be (diff)
downloadkernel_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.c26
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);