Blob Blame History Raw
From 48bd024b8a40d73ad6b086de2615738da0c7004f Mon Sep 17 00:00:00 2001
From: Miklos Szeredi <mszeredi@redhat.com>
Date: Tue Jun  2 22:20:25 2020 +0200
Subject: [PATCH] ovl: switch to mounter creds in readdir 
Git-commit: 48bd024b8a40d73ad6b086de2615738da0c7004f
References: bsc#1177470, CVE-2020-16120
Patch-mainline: v5.7

In preparation for more permission checking, override credentials for
directory operations on the underlying filesystems.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>

---
 fs/overlayfs/readdir.c |   26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

--- a/fs/overlayfs/readdir.c
+++ b/fs/overlayfs/readdir.c
@@ -358,19 +358,25 @@
 	struct ovl_dir_file *od = file->private_data;
 	struct dentry *dentry = file->f_path.dentry;
 	struct ovl_cache_entry *p;
+	const struct cred *old_cred;
+	int err;
 
+	old_cred = ovl_override_creds(dentry->d_sb);
 	if (!ctx->pos)
 		ovl_dir_reset(file);
 
-	if (od->is_real)
-		return iterate_dir(od->realfile, ctx);
+	if (od->is_real) {
+		err = iterate_dir(od->realfile, ctx);
+		goto out;
+	}
 
 	if (!od->cache) {
 		struct ovl_dir_cache *cache;
 
 		cache = ovl_cache_get(dentry);
+		err = PTR_ERR(cache);
 		if (IS_ERR(cache))
-			return PTR_ERR(cache);
+			goto out;
 
 		od->cache = cache;
 		ovl_seek_cursor(od, ctx->pos);
@@ -384,7 +390,10 @@
 		od->cursor = p->l_node.next;
 		ctx->pos++;
 	}
-	return 0;
+	err = 0;
+out:
+	revert_creds(old_cred);
+	return err;
 }
 
 static loff_t ovl_dir_llseek(struct file *file, loff_t offset, int origin)
@@ -430,7 +439,14 @@
 static struct file *ovl_dir_open_realfile(struct file *file,
 					  struct path *realpath)
 {
-	return ovl_path_open(realpath, O_RDONLY | (file->f_flags & O_LARGEFILE));
+	struct file *res;
+	const struct cred *old_cred;
+
+	old_cred = ovl_override_creds(file_inode(file)->i_sb);
+	res = ovl_path_open(realpath, O_RDONLY | (file->f_flags & O_LARGEFILE));
+	revert_creds(old_cred);
+
+	return res;
 }
 
 static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end,