]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.14.129/abort-file_remove_privs-for-non-reg.-files.patch
Linux 4.14.129
[thirdparty/kernel/stable-queue.git] / releases / 4.14.129 / abort-file_remove_privs-for-non-reg.-files.patch
CommitLineData
f0588f72
GKH
1From f69e749a49353d96af1a293f56b5b56de59c668a Mon Sep 17 00:00:00 2001
2From: Alexander Lochmann <alexander.lochmann@tu-dortmund.de>
3Date: Fri, 14 Dec 2018 11:55:52 +0100
4Subject: Abort file_remove_privs() for non-reg. files
5
6From: Alexander Lochmann <alexander.lochmann@tu-dortmund.de>
7
8commit f69e749a49353d96af1a293f56b5b56de59c668a upstream.
9
10file_remove_privs() might be called for non-regular files, e.g.
11blkdev inode. There is no reason to do its job on things
12like blkdev inodes, pipes, or cdevs. Hence, abort if
13file does not refer to a regular inode.
14
15AV: more to the point, for devices there might be any number of
16inodes refering to given device. Which one to strip the permissions
17from, even if that made any sense in the first place? All of them
18will be observed with contents modified, after all.
19
20Found by LockDoc (Alexander Lochmann, Horst Schirmeier and Olaf
21Spinczyk)
22
23Reviewed-by: Jan Kara <jack@suse.cz>
24Signed-off-by: Alexander Lochmann <alexander.lochmann@tu-dortmund.de>
25Signed-off-by: Horst Schirmeier <horst.schirmeier@tu-dortmund.de>
26Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
27Cc: Zubin Mithra <zsm@chromium.org>
28Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
29
30---
31 fs/inode.c | 9 +++++++--
32 1 file changed, 7 insertions(+), 2 deletions(-)
33
34--- a/fs/inode.c
35+++ b/fs/inode.c
36@@ -1817,8 +1817,13 @@ int file_remove_privs(struct file *file)
37 int kill;
38 int error = 0;
39
40- /* Fast path for nothing security related */
41- if (IS_NOSEC(inode))
42+ /*
43+ * Fast path for nothing security related.
44+ * As well for non-regular files, e.g. blkdev inodes.
45+ * For example, blkdev_write_iter() might get here
46+ * trying to remove privs which it is not allowed to.
47+ */
48+ if (IS_NOSEC(inode) || !S_ISREG(inode->i_mode))
49 return 0;
50
51 kill = dentry_needs_remove_privs(dentry);