changes: we do not have fs_fully_visible so skip its hunk
(we do not inherit flags so we do not need to cut them), also
skip hunk in do_remount.

git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git 
for-testing
commit 4aceccd65a57 ("userns: Simpilify MNT_NODEV handling.")

- Consolidate the testing if a device node may be opened in a new
  function may_open_dev.

- Move the check for allowing access to device nodes on filesystems
  not mounted in the initial user namespace from mount time to open
  time and include it in may_open_dev.

This set of changes removes the implicit adding of MNT_NODEV which
simplifies the logic in fs/namespace.c and removes a potentially
problematic difference in how normal and unprivileged mount
namespaces work.  This is a user visible change in behavior for
remount in unpriviliged mount namespaces but is unlikely to cause
problems for existing software.

Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: Pavel Tikhomirov <[email protected]>
---
 fs/block_dev.c     | 2 +-
 fs/namei.c         | 9 ++++++++-
 fs/namespace.c     | 7 -------
 include/linux/fs.h | 1 +
 4 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/fs/block_dev.c b/fs/block_dev.c
index 65e7757..b8533ea 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1656,7 +1656,7 @@ struct block_device *lookup_bdev(const char *pathname)
        if (!S_ISBLK(inode->i_mode))
                goto fail;
        error = -EACCES;
-       if (path.mnt->mnt_flags & MNT_NODEV)
+       if (!may_open_dev(&path))
                goto fail;
        error = -ENOMEM;
        bdev = bd_acquire(inode);
diff --git a/fs/namei.c b/fs/namei.c
index 16820b1..0f12ce7 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2602,6 +2602,13 @@ int vfs_create(struct inode *dir, struct dentry *dentry, 
umode_t mode,
        return error;
 }
 
+bool may_open_dev(const struct path *path)
+{
+       return !(path->mnt->mnt_flags & MNT_NODEV) &&
+               ((path->mnt->mnt_sb->s_user_ns == &init_user_ns) ||
+                (path->mnt->mnt_sb->s_type->fs_flags & FS_USERNS_DEV_MOUNT));
+}
+
 static int may_open(struct path *path, int acc_mode, int flag)
 {
        struct dentry *dentry = path->dentry;
@@ -2624,7 +2631,7 @@ static int may_open(struct path *path, int acc_mode, int 
flag)
                break;
        case S_IFBLK:
        case S_IFCHR:
-               if (path->mnt->mnt_flags & MNT_NODEV)
+               if (!may_open_dev(path))
                        return -EACCES;
                /*FALLTHRU*/
        case S_IFIFO:
diff --git a/fs/namespace.c b/fs/namespace.c
index 637ed20..bea4ebf 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2232,13 +2232,6 @@ static int do_new_mount(struct path *path, const char 
*fstype, int flags,
                        put_filesystem(type);
                        return -EPERM;
                }
-               /* Only in special cases allow devices from mounts
-                * created outside the initial user namespace.
-                */
-               if (!(type->fs_flags & FS_USERNS_DEV_MOUNT)) {
-                       flags |= MS_NODEV;
-                       mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV;
-               }
        }
 
        mnt = vfs_kern_mount(type, flags, name, data);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e6b6e6b..cf439ef 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1728,6 +1728,7 @@ extern void dentry_unhash(struct dentry *dentry);
  */
 extern void inode_init_owner(struct inode *inode, const struct inode *dir,
                        umode_t mode);
+extern bool may_open_dev(const struct path *path);
 /*
  * VFS FS_IOC_FIEMAP helper definitions.
  */
-- 
1.9.3

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to