aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2015-05-09 00:49:47 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-07-21 13:10:01 -0400
commit51c2c47ef6349d49e49002054f8c0d11d3b5646e (patch)
treeb29286feaa7f9992d4eaef98a3c1461c10d82abb /fs
parentb5eb51f2ee063044401492650e9e01bb35974870 (diff)
mnt: Modify fs_fully_visible to deal with locked ro nodev and atime
commit 8c6cf9cc829fcd0b179b59f7fe288941d0e31108 upstream. Ignore an existing mount if the locked readonly, nodev or atime attributes are less permissive than the desired attributes of the new mount. On success ensure the new mount locks all of the same readonly, nodev and atime attributes as the old mount. The nosuid and noexec attributes are not checked here as this change is destined for stable and enforcing those attributes causes a regression in lxc and libvirt-lxc where those applications will not start and there are no known executables on sysfs or proc and no known way to create exectuables without code modifications Fixes: e51db73532955 ("userns: Better restrictions on when proc and sysfs can be mounted") Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/namespace.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 50a0d950404c..02c6875dd945 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2332,7 +2332,7 @@ unlock:
2332 return err; 2332 return err;
2333} 2333}
2334 2334
2335static bool fs_fully_visible(struct file_system_type *fs_type); 2335static bool fs_fully_visible(struct file_system_type *fs_type, int *new_mnt_flags);
2336 2336
2337/* 2337/*
2338 * create a new mount for userspace and request it to be added into the 2338 * create a new mount for userspace and request it to be added into the
@@ -2366,7 +2366,7 @@ static int do_new_mount(struct path *path, const char *fstype, int flags,
2366 mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV; 2366 mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV;
2367 } 2367 }
2368 if (type->fs_flags & FS_USERNS_VISIBLE) { 2368 if (type->fs_flags & FS_USERNS_VISIBLE) {
2369 if (!fs_fully_visible(type)) 2369 if (!fs_fully_visible(type, &mnt_flags))
2370 return -EPERM; 2370 return -EPERM;
2371 } 2371 }
2372 } 2372 }
@@ -3170,9 +3170,10 @@ bool current_chrooted(void)
3170 return chrooted; 3170 return chrooted;
3171} 3171}
3172 3172
3173static bool fs_fully_visible(struct file_system_type *type) 3173static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags)
3174{ 3174{
3175 struct mnt_namespace *ns = current->nsproxy->mnt_ns; 3175 struct mnt_namespace *ns = current->nsproxy->mnt_ns;
3176 int new_flags = *new_mnt_flags;
3176 struct mount *mnt; 3177 struct mount *mnt;
3177 bool visible = false; 3178 bool visible = false;
3178 3179
@@ -3191,6 +3192,19 @@ static bool fs_fully_visible(struct file_system_type *type)
3191 if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root) 3192 if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root)
3192 continue; 3193 continue;
3193 3194
3195 /* Verify the mount flags are equal to or more permissive
3196 * than the proposed new mount.
3197 */
3198 if ((mnt->mnt.mnt_flags & MNT_LOCK_READONLY) &&
3199 !(new_flags & MNT_READONLY))
3200 continue;
3201 if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) &&
3202 !(new_flags & MNT_NODEV))
3203 continue;
3204 if ((mnt->mnt.mnt_flags & MNT_LOCK_ATIME) &&
3205 ((mnt->mnt.mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK)))
3206 continue;
3207
3194 /* This mount is not fully visible if there are any 3208 /* This mount is not fully visible if there are any
3195 * locked child mounts that cover anything except for 3209 * locked child mounts that cover anything except for
3196 * empty directories. 3210 * empty directories.
@@ -3204,6 +3218,10 @@ static bool fs_fully_visible(struct file_system_type *type)
3204 if (!is_empty_dir_inode(inode)) 3218 if (!is_empty_dir_inode(inode))
3205 goto next; 3219 goto next;
3206 } 3220 }
3221 /* Preserve the locked attributes */
3222 *new_mnt_flags |= mnt->mnt.mnt_flags & (MNT_LOCK_READONLY | \
3223 MNT_LOCK_NODEV | \
3224 MNT_LOCK_ATIME);
3207 visible = true; 3225 visible = true;
3208 goto found; 3226 goto found;
3209 next: ; 3227 next: ;