Thread (247 messages) 247 messages, 5 authors, 2016-03-04

[added to the 4.1 stable tree] ovl: setattr: check permissions before copy-up

From: Sasha Levin <hidden>
Date: 2016-02-10 15:12:39
Subsystem: filesystems (vfs and infrastructure), overlay filesystem, the rest · Maintainers: Alexander Viro, Christian Brauner, Miklos Szeredi, Amir Goldstein, Linus Torvalds

From: Miklos Szeredi <miklos@szeredi.hu>

This patch has been added to the 4.1 stable tree. If you have any
objections, please let us know.

===============

[ Upstream commit cf9a6784f7c1b5ee2b9159a1246e327c331c5697 ]

Without this copy-up of a file can be forced, even without actually being
allowed to do anything on the file.

[Arnd Bergmann] include <linux/pagemap.h> for PAGE_CACHE_SIZE (used by
MAX_LFS_FILESIZE definition).

Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
Cc: <redacted>
Signed-off-by: Sasha Levin <redacted>
---
 fs/overlayfs/inode.c | 13 +++++++++++++
 fs/overlayfs/super.c |  2 ++
 2 files changed, 15 insertions(+)
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index ba0db26..a1b069e 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -45,6 +45,19 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
 	int err;
 	struct dentry *upperdentry;
 
+	/*
+	 * Check for permissions before trying to copy-up.  This is redundant
+	 * since it will be rechecked later by ->setattr() on upper dentry.  But
+	 * without this, copy-up can be triggered by just about anybody.
+	 *
+	 * We don't initialize inode->size, which just means that
+	 * inode_newsize_ok() will always check against MAX_LFS_FILESIZE and not
+	 * check for a swapfile (which this won't be anyway).
+	 */
+	err = inode_change_ok(dentry->d_inode, attr);
+	if (err)
+		return err;
+
 	err = ovl_want_write(dentry);
 	if (err)
 		goto out;
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index c4b595e..bd6d5c1 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -9,6 +9,7 @@
 
 #include <linux/fs.h>
 #include <linux/namei.h>
+#include <linux/pagemap.h>
 #include <linux/xattr.h>
 #include <linux/security.h>
 #include <linux/mount.h>
@@ -847,6 +848,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
 	}
 
 	sb->s_stack_depth = 0;
+	sb->s_maxbytes = MAX_LFS_FILESIZE;
 	if (ufs->config.upperdir) {
 		if (!ufs->config.workdir) {
 			pr_err("overlayfs: missing 'workdir'\n");
-- 
2.5.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help