Skip to content

Commit

Permalink
vfs: Only support slave subtrees across different user namespaces
Browse files Browse the repository at this point in the history
Sharing mount subtress with mount namespaces created by unprivileged
users allows unprivileged mounts created by unprivileged users to
propagate to mount namespaces controlled by privileged users.

Prevent nasty consequences by changing shared subtrees to slave
subtress when an unprivileged users creates a new mount namespace.

Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
  • Loading branch information
Eric W. Biederman committed Nov 19, 2012
1 parent 771b137 commit 7a472ef
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 3 deletions.
11 changes: 8 additions & 3 deletions fs/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
if (!mnt)
return ERR_PTR(-ENOMEM);

if (flag & (CL_SLAVE | CL_PRIVATE))
if (flag & (CL_SLAVE | CL_PRIVATE | CL_SHARED_TO_SLAVE))
mnt->mnt_group_id = 0; /* not a peer of original */
else
mnt->mnt_group_id = old->mnt_group_id;
Expand All @@ -807,7 +807,8 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
list_add_tail(&mnt->mnt_instance, &sb->s_mounts);
br_write_unlock(&vfsmount_lock);

if (flag & CL_SLAVE) {
if ((flag & CL_SLAVE) ||
((flag & CL_SHARED_TO_SLAVE) && IS_MNT_SHARED(old))) {
list_add(&mnt->mnt_slave, &old->mnt_slave_list);
mnt->mnt_master = old;
CLEAR_MNT_SHARED(mnt);
Expand Down Expand Up @@ -2331,14 +2332,18 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
struct mount *p, *q;
struct mount *old = mnt_ns->root;
struct mount *new;
int copy_flags;

new_ns = alloc_mnt_ns(user_ns);
if (IS_ERR(new_ns))
return new_ns;

down_write(&namespace_sem);
/* First pass: copy the tree topology */
new = copy_tree(old, old->mnt.mnt_root, CL_COPY_ALL | CL_EXPIRE);
copy_flags = CL_COPY_ALL | CL_EXPIRE;
if (user_ns != mnt_ns->user_ns)
copy_flags |= CL_SHARED_TO_SLAVE;
new = copy_tree(old, old->mnt.mnt_root, copy_flags);
if (IS_ERR(new)) {
up_write(&namespace_sem);
free_mnt_ns(new_ns);
Expand Down
1 change: 1 addition & 0 deletions fs/pnode.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define CL_COPY_ALL 0x04
#define CL_MAKE_SHARED 0x08
#define CL_PRIVATE 0x10
#define CL_SHARED_TO_SLAVE 0x20

static inline void set_mnt_shared(struct mount *mnt)
{
Expand Down

0 comments on commit 7a472ef

Please sign in to comment.