summaryrefslogtreecommitdiff
path: root/fs/overlayfs/file.c
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2020-06-02 22:20:26 +0200
committerMiklos Szeredi <mszeredi@redhat.com>2020-06-03 09:45:22 +0200
commit05acefb4872dae89e772729efb194af754c877e8 (patch)
tree9a53947fdb6ac28bca724cfb7a05090fea1f3b8d /fs/overlayfs/file.c
parent292f902a40c11f043a5ca1305a114da0e523eaa3 (diff)
ovl: check permission to open real file
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>
Diffstat (limited to 'fs/overlayfs/file.c')
-rw-r--r--fs/overlayfs/file.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
index 1860e220c82d..0f83c8dfec46 100644
--- a/fs/overlayfs/file.c
+++ b/fs/overlayfs/file.c
@@ -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",