]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.9.174/debugfs-fix-use-after-free-on-symlink-traversal.patch
fix up queue-3.18/ipv6-flowlabel-wait-rcu-grace-period-before-put_pid.patch
[thirdparty/kernel/stable-queue.git] / releases / 4.9.174 / debugfs-fix-use-after-free-on-symlink-traversal.patch
1 From 539064db73c050f0fa7b5bbe326fa45e9773af8b Mon Sep 17 00:00:00 2001
2 From: Al Viro <viro@zeniv.linux.org.uk>
3 Date: Tue, 26 Mar 2019 01:43:37 +0000
4 Subject: debugfs: fix use-after-free on symlink traversal
5
6 [ Upstream commit 93b919da64c15b90953f96a536e5e61df896ca57 ]
7
8 symlink body shouldn't be freed without an RCU delay. Switch debugfs to
9 ->destroy_inode() and use of call_rcu(); free both the inode and symlink
10 body in the callback. Similar to solution for bpf, only here it's even
11 more obvious that ->evict_inode() can be dropped.
12
13 Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
14 Signed-off-by: Sasha Levin <sashal@kernel.org>
15 ---
16 fs/debugfs/inode.c | 13 +++++++++----
17 1 file changed, 9 insertions(+), 4 deletions(-)
18
19 diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
20 index 77e9cd7a0137..20ee612017bf 100644
21 --- a/fs/debugfs/inode.c
22 +++ b/fs/debugfs/inode.c
23 @@ -170,19 +170,24 @@ static int debugfs_show_options(struct seq_file *m, struct dentry *root)
24 return 0;
25 }
26
27 -static void debugfs_evict_inode(struct inode *inode)
28 +static void debugfs_i_callback(struct rcu_head *head)
29 {
30 - truncate_inode_pages_final(&inode->i_data);
31 - clear_inode(inode);
32 + struct inode *inode = container_of(head, struct inode, i_rcu);
33 if (S_ISLNK(inode->i_mode))
34 kfree(inode->i_link);
35 + free_inode_nonrcu(inode);
36 +}
37 +
38 +static void debugfs_destroy_inode(struct inode *inode)
39 +{
40 + call_rcu(&inode->i_rcu, debugfs_i_callback);
41 }
42
43 static const struct super_operations debugfs_super_operations = {
44 .statfs = simple_statfs,
45 .remount_fs = debugfs_remount,
46 .show_options = debugfs_show_options,
47 - .evict_inode = debugfs_evict_inode,
48 + .destroy_inode = debugfs_destroy_inode,
49 };
50
51 static struct vfsmount *debugfs_automount(struct path *path)
52 --
53 2.20.1
54