From 8ad08d8a0c3823e9b06ef84c362c9361be323d2d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 16 Jan 2010 12:56:08 -0500 Subject: may_umount() needs namespace_sem otherwise it races with clone_mnt() changing mnt_share/mnt_slaves Signed-off-by: Al Viro --- fs/namespace.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs/namespace.c') diff --git a/fs/namespace.c b/fs/namespace.c index 7d70d63ceb2..461090a57b3 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -965,10 +965,12 @@ EXPORT_SYMBOL(may_umount_tree); int may_umount(struct vfsmount *mnt) { int ret = 1; + down_read(&namespace_sem); spin_lock(&vfsmount_lock); if (propagate_mount_busy(mnt, 2)) ret = 0; spin_unlock(&vfsmount_lock); + up_read(&namespace_sem); return ret; } -- cgit v1.2.3-70-g09d2 From df1a1ad29739f032f8905310796e558589403d61 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 16 Jan 2010 12:57:40 -0500 Subject: attach_recursive_mnt() needs to hold vfsmount_lock over set_mnt_shared() race in mnt_flags update Signed-off-by: Al Viro --- fs/namespace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/namespace.c') diff --git a/fs/namespace.c b/fs/namespace.c index 461090a57b3..4de493ea67c 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1354,12 +1354,12 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt, if (err) goto out_cleanup_ids; + spin_lock(&vfsmount_lock); + if (IS_MNT_SHARED(dest_mnt)) { for (p = source_mnt; p; p = next_mnt(p, source_mnt)) set_mnt_shared(p); } - - spin_lock(&vfsmount_lock); if (parent_path) { detach_mnt(source_mnt, parent_path); attach_mnt(source_mnt, path); -- cgit v1.2.3-70-g09d2 From 7b43a79f32c0a05e7562043af98e25c05c89b18e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 16 Jan 2010 13:01:26 -0500 Subject: mnt_flags fixes in do_remount() * need vfsmount_lock over modifying it * need to preserve MNT_SHARED/MNT_UNBINDABLE Signed-off-by: Al Viro --- fs/namespace.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'fs/namespace.c') diff --git a/fs/namespace.c b/fs/namespace.c index 4de493ea67c..779293e29b8 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1536,8 +1536,12 @@ static int do_remount(struct path *path, int flags, int mnt_flags, err = change_mount_flags(path->mnt, flags); else err = do_remount_sb(sb, flags, data, 0); - if (!err) + if (!err) { + spin_lock(&vfsmount_lock); + mnt_flags |= path->mnt->mnt_flags & MNT_PNODE_MASK; path->mnt->mnt_flags = mnt_flags; + spin_unlock(&vfsmount_lock); + } up_write(&sb->s_umount); if (!err) { security_sb_post_remount(path->mnt, flags, data); -- cgit v1.2.3-70-g09d2 From 27d55f1f4c190b14092fcca3069c7d15df83514f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 16 Jan 2010 13:07:36 -0500 Subject: do_add_mount() should sanitize mnt_flags MNT_WRITE_HOLD shouldn't leak into new vfsmount and neither should MNT_SHARED (the latter will be set properly, along with the rest of shared-subtree data structures) Signed-off-by: Al Viro --- fs/namespace.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs/namespace.c') diff --git a/fs/namespace.c b/fs/namespace.c index 779293e29b8..c768f733c8d 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1671,6 +1671,8 @@ int do_add_mount(struct vfsmount *newmnt, struct path *path, { int err; + mnt_flags &= ~(MNT_SHARED | MNT_WRITE_HOLD); + down_write(&namespace_sem); /* Something was mounted here while we slept */ while (d_mountpoint(path->dentry) && -- cgit v1.2.3-70-g09d2