From d561f218564855f69791216882a2622af37e5776 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 18 Jul 2018 15:44:43 +0200 Subject: Revert "ovl: fix may_write_real() for overlayfs directories" This reverts commit 954c736f865d6c0c68ae4263a2f3502ee7c447a3. Overlayfs no longer relies on the vfs for checking writability of files. Signed-off-by: Miklos Szeredi --- fs/namespace.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'fs/namespace.c') diff --git a/fs/namespace.c b/fs/namespace.c index 8ddd14806799..76a742e36b32 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -468,9 +468,7 @@ static inline int may_write_real(struct file *file) /* File refers to upper, writable layer? */ upperdentry = d_real(dentry, NULL, 0, D_REAL_UPPER); - if (upperdentry && - (file_inode(file) == d_inode(upperdentry) || - file_inode(file) == d_inode(dentry))) + if (upperdentry && file_inode(file) == d_inode(upperdentry)) return 0; /* Lower layer: can't write to real file, sorry... */ -- cgit From 6742cee04353231015ddbe7e8b404ac9c1eb4473 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 18 Jul 2018 15:44:43 +0200 Subject: Revert "ovl: don't allow writing ioctl on lower layer" This reverts commit 7c6893e3c9abf6a9676e060a1e35e5caca673d57. Overlayfs no longer relies on the vfs for checking writability of files. Signed-off-by: Miklos Szeredi --- fs/namespace.c | 64 +++------------------------------------------------------- 1 file changed, 3 insertions(+), 61 deletions(-) (limited to 'fs/namespace.c') diff --git a/fs/namespace.c b/fs/namespace.c index 76a742e36b32..c16921dba157 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -431,18 +431,13 @@ int __mnt_want_write_file(struct file *file) } /** - * mnt_want_write_file_path - get write access to a file's mount + * mnt_want_write_file - get write access to a file's mount * @file: the file who's mount on which to take a write * * This is like mnt_want_write, but it takes a file and can * do some optimisations if the file is open for write already - * - * Called by the vfs for cases when we have an open file at hand, but will do an - * inode operation on it (important distinction for files opened on overlayfs, - * since the file operations will come from the real underlying file, while - * inode operations come from the overlay). */ -int mnt_want_write_file_path(struct file *file) +int mnt_want_write_file(struct file *file) { int ret; @@ -452,53 +447,6 @@ int mnt_want_write_file_path(struct file *file) sb_end_write(file->f_path.mnt->mnt_sb); return ret; } - -static inline int may_write_real(struct file *file) -{ - struct dentry *dentry = file->f_path.dentry; - struct dentry *upperdentry; - - /* Writable file? */ - if (file->f_mode & FMODE_WRITER) - return 0; - - /* Not overlayfs? */ - if (likely(!(dentry->d_flags & DCACHE_OP_REAL))) - return 0; - - /* File refers to upper, writable layer? */ - upperdentry = d_real(dentry, NULL, 0, D_REAL_UPPER); - if (upperdentry && file_inode(file) == d_inode(upperdentry)) - return 0; - - /* Lower layer: can't write to real file, sorry... */ - return -EPERM; -} - -/** - * mnt_want_write_file - get write access to a file's mount - * @file: the file who's mount on which to take a write - * - * This is like mnt_want_write, but it takes a file and can - * do some optimisations if the file is open for write already - * - * Mostly called by filesystems from their ioctl operation before performing - * modification. On overlayfs this needs to check if the file is on a read-only - * lower layer and deny access in that case. - */ -int mnt_want_write_file(struct file *file) -{ - int ret; - - ret = may_write_real(file); - if (!ret) { - sb_start_write(file_inode(file)->i_sb); - ret = __mnt_want_write_file(file); - if (ret) - sb_end_write(file_inode(file)->i_sb); - } - return ret; -} EXPORT_SYMBOL_GPL(mnt_want_write_file); /** @@ -536,15 +484,9 @@ void __mnt_drop_write_file(struct file *file) __mnt_drop_write(file->f_path.mnt); } -void mnt_drop_write_file_path(struct file *file) -{ - mnt_drop_write(file->f_path.mnt); -} - void mnt_drop_write_file(struct file *file) { - __mnt_drop_write(file->f_path.mnt); - sb_end_write(file_inode(file)->i_sb); + mnt_drop_write(file->f_path.mnt); } EXPORT_SYMBOL(mnt_drop_write_file); -- cgit From a6795a585929d94ca3e931bc8518f8deb8bbe627 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 18 Jul 2018 15:44:43 +0200 Subject: vfs: fix freeze protection in mnt_want_write_file() for overlayfs The underlying real file used by overlayfs still contains the overlay path. This results in mnt_want_write_file() calls by the filesystem getting freeze protection on the wrong inode (the overlayfs one instead of the real one). Fix by using file_inode(file)->i_sb instead of file->f_path.mnt->mnt_sb. Reported-by: Amir Goldstein Signed-off-by: Miklos Szeredi Reviewed-by: Christoph Hellwig --- fs/namespace.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'fs/namespace.c') diff --git a/fs/namespace.c b/fs/namespace.c index c16921dba157..9be2e938d36f 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -441,10 +441,10 @@ int mnt_want_write_file(struct file *file) { int ret; - sb_start_write(file->f_path.mnt->mnt_sb); + sb_start_write(file_inode(file)->i_sb); ret = __mnt_want_write_file(file); if (ret) - sb_end_write(file->f_path.mnt->mnt_sb); + sb_end_write(file_inode(file)->i_sb); return ret; } EXPORT_SYMBOL_GPL(mnt_want_write_file); @@ -486,7 +486,8 @@ void __mnt_drop_write_file(struct file *file) void mnt_drop_write_file(struct file *file) { - mnt_drop_write(file->f_path.mnt); + __mnt_drop_write_file(file); + sb_end_write(file_inode(file)->i_sb); } EXPORT_SYMBOL(mnt_drop_write_file); -- cgit