summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Lochmann <alexander.lochmann@tu-dortmund.de>2018-12-14 11:55:52 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-06-22 08:15:21 +0200
commite8e448b08450b05d54cf99eb4e3473b708c8fcc0 (patch)
treead0a05280f63a3d776e509199b0e071eb0c0606e
parent465ce9a50f8a4e2fcd257ce37e11db3104a83ebb (diff)
downloadlinux-stable-e8e448b08450b05d54cf99eb4e3473b708c8fcc0.tar.gz
linux-stable-e8e448b08450b05d54cf99eb4e3473b708c8fcc0.tar.bz2
linux-stable-e8e448b08450b05d54cf99eb4e3473b708c8fcc0.zip
Abort file_remove_privs() for non-reg. files
commit f69e749a49353d96af1a293f56b5b56de59c668a upstream. file_remove_privs() might be called for non-regular files, e.g. blkdev inode. There is no reason to do its job on things like blkdev inodes, pipes, or cdevs. Hence, abort if file does not refer to a regular inode. AV: more to the point, for devices there might be any number of inodes refering to given device. Which one to strip the permissions from, even if that made any sense in the first place? All of them will be observed with contents modified, after all. Found by LockDoc (Alexander Lochmann, Horst Schirmeier and Olaf Spinczyk) Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Alexander Lochmann <alexander.lochmann@tu-dortmund.de> Signed-off-by: Horst Schirmeier <horst.schirmeier@tu-dortmund.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Cc: Zubin Mithra <zsm@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/inode.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/inode.c b/fs/inode.c
index 42f6d25f32a5..5c63693326bb 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1817,8 +1817,13 @@ int file_remove_privs(struct file *file)
int kill;
int error = 0;
- /* Fast path for nothing security related */
- if (IS_NOSEC(inode))
+ /*
+ * Fast path for nothing security related.
+ * As well for non-regular files, e.g. blkdev inodes.
+ * For example, blkdev_write_iter() might get here
+ * trying to remove privs which it is not allowed to.
+ */
+ if (IS_NOSEC(inode) || !S_ISREG(inode->i_mode))
return 0;
kill = dentry_needs_remove_privs(dentry);