ovl: check permission to open real file
authorMiklos Szeredi <mszeredi@redhat.com>
Tue, 2 Jun 2020 20:20:26 +0000 (22:20 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Wed, 3 Jun 2020 07:45:22 +0000 (09:45 +0200)
Call inode_permission() on real inode before opening regular file on one of
the underlying layers.

In some cases ovl_permission() already checks access to an underlying file,
but it misses the metacopy case, and possibly other ones as well.

Removing the redundant permission check from ovl_permission() should be
considered later.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/overlayfs/file.c

index 1860e22..0f83c8d 100644 (file)
@@ -40,10 +40,22 @@ static struct file *ovl_open_realfile(const struct file *file,
        struct file *realfile;
        const struct cred *old_cred;
        int flags = file->f_flags | O_NOATIME | FMODE_NONOTIFY;
+       int acc_mode = ACC_MODE(flags);
+       int err;
+
+       if (flags & O_APPEND)
+               acc_mode |= MAY_APPEND;
 
        old_cred = ovl_override_creds(inode->i_sb);
-       realfile = open_with_fake_path(&file->f_path, flags, realinode,
-                                      current_cred());
+       err = inode_permission(realinode, MAY_OPEN | acc_mode);
+       if (err) {
+               realfile = ERR_PTR(err);
+       } else if (!inode_owner_or_capable(realinode)) {
+               realfile = ERR_PTR(-EPERM);
+       } else {
+               realfile = open_with_fake_path(&file->f_path, flags, realinode,
+                                              current_cred());
+       }
        revert_creds(old_cred);
 
        pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n",