[PATCH] userns: introduce new mount option MS_LOCK

From: Gao feng
Date: Wed Nov 13 2013 - 03:06:46 EST


After commit 5ff9d8a65ce80efb509ce4e8051394e9ed2cd942
vfs: Lock in place mounts from more privileged users,
in userns, the mounts of child mntns which copied from
parent mntns is locked and user has no rights to umount/move
them, it's too strict.

The core purpose of above commit is trying to prevent
unprivileged user from accessing files hidden by mount.
This patch introduces a new mount option MS_LOCK, this
gives user the capable to mount filesystem as the type
of lock if he wants to use mount to hide something.

And this patch also makes it possible to resolve the
problem brought by commit e51db73532955dc5eaba4235e62b74b460709d5b,
the i_nlink is incorrect in some filesystems.

Signed-off-by: Gao feng <gaofeng@xxxxxxxxxxxxxx>
---
fs/namespace.c | 10 ++++------
fs/proc_namespace.c | 1 +
include/uapi/linux/fs.h | 1 +
3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/namespace.c b/fs/namespace.c
index 7097fc7..8e6b3e8 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -830,10 +830,6 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
if ((flag & CL_UNPRIVILEGED) && (mnt->mnt.mnt_flags & MNT_READONLY))
mnt->mnt.mnt_flags |= MNT_LOCK_READONLY;

- /* Don't allow unprivileged users to reveal what is under a mount */
- if ((flag & CL_UNPRIVILEGED) && list_empty(&old->mnt_expire))
- mnt->mnt.mnt_flags |= MNT_LOCKED;
-
atomic_inc(&sb->s_active);
mnt->mnt.mnt_sb = sb;
mnt->mnt.mnt_root = dget(root);
@@ -2359,10 +2355,12 @@ long do_mount(const char *dev_name, const char *dir_name,
mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME);
if (flags & MS_RDONLY)
mnt_flags |= MNT_READONLY;
+ if (flags & MS_LOCK)
+ mnt_flags |= MNT_LOCKED;

flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN |
MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
- MS_STRICTATIME);
+ MS_STRICTATIME | MS_LOCK);

if (flags & MS_REMOUNT)
retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
@@ -2894,7 +2892,7 @@ bool fs_fully_visible(struct file_system_type *type)
struct inode *inode = child->mnt_mountpoint->d_inode;
if (!S_ISDIR(inode->i_mode))
goto next;
- if (inode->i_nlink != 2)
+ if (!may_mount_lock(child))
goto next;
}
visible = true;
diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c
index 5fe34c3..fc9b15c 100644
--- a/fs/proc_namespace.c
+++ b/fs/proc_namespace.c
@@ -65,6 +65,7 @@ static void show_mnt_opts(struct seq_file *m, struct vfsmount *mnt)
{ MNT_NOATIME, ",noatime" },
{ MNT_NODIRATIME, ",nodiratime" },
{ MNT_RELATIME, ",relatime" },
+ { MNT_LOCKED, ",locked" },
{ 0, NULL }
};
const struct proc_fs_info *fs_infop;
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index 6c28b61..731d894 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -69,6 +69,7 @@ struct inodes_stat_t {
#define MS_REMOUNT 32 /* Alter flags of a mounted FS */
#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
#define MS_DIRSYNC 128 /* Directory modifications are synchronous */
+#define MS_LOCK 512 /* Disallow unpriviged user to umount FS. */
#define MS_NOATIME 1024 /* Do not update access times. */
#define MS_NODIRATIME 2048 /* Do not update directory access times */
#define MS_BIND 4096
--
1.8.3.1


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/