From 71dc01f23938fbffc93546a853f4f2b7174fce74 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 16 Mar 2021 20:56:06 +0800 Subject: [PATCH] ovl: check permission to open real file mainline inclusion from mainline-v5.8-rc1 commit 05acefb4872dae89e772729efb194af754c877e8 category: bugfix bugzilla: NA CVE: CVE-2020-16120 -------------------------------- 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 Conflicts: fs/overlayfs/file.c [yyl: adjust context] Signed-off-by: Yang Yingliang Reviewed-by: zhangyi (F) Signed-off-by: Yang Yingliang Acked-by: Xie XiuQi Signed-off-by: Cheng Jian --- fs/overlayfs/file.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index b4ab06c3f3c6..f8e733c29cc4 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -35,10 +35,22 @@ static struct file *ovl_open_realfile(const struct file *file, struct file *realfile; const struct cred *old_cred; int flags = file->f_flags | OVL_OPEN_FLAGS; + 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", -- GitLab