]>
Commit | Line | Data |
---|---|---|
e6832405 SL |
1 | From e1015a2094030d45cdad3e9540effcab7392f8a7 Mon Sep 17 00:00:00 2001 |
2 | From: Al Viro <viro@zeniv.linux.org.uk> | |
3 | Date: Wed, 10 Apr 2019 14:04:34 -0400 | |
4 | Subject: apparmorfs: fix use-after-free on symlink traversal | |
5 | ||
6 | [ Upstream commit f51dcd0f621caac5380ce90fbbeafc32ce4517ae ] | |
7 | ||
8 | symlink body shouldn't be freed without an RCU delay. Switch apparmorfs | |
9 | to ->destroy_inode() and use of call_rcu(); free both the inode and symlink | |
10 | body in the callback. | |
11 | ||
12 | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> | |
13 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
14 | --- | |
15 | security/apparmor/apparmorfs.c | 13 +++++++++---- | |
16 | 1 file changed, 9 insertions(+), 4 deletions(-) | |
17 | ||
18 | diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c | |
19 | index 3f80a684c232a..665853dd517ca 100644 | |
20 | --- a/security/apparmor/apparmorfs.c | |
21 | +++ b/security/apparmor/apparmorfs.c | |
22 | @@ -123,17 +123,22 @@ static int aafs_show_path(struct seq_file *seq, struct dentry *dentry) | |
23 | return 0; | |
24 | } | |
25 | ||
26 | -static void aafs_evict_inode(struct inode *inode) | |
27 | +static void aafs_i_callback(struct rcu_head *head) | |
28 | { | |
29 | - truncate_inode_pages_final(&inode->i_data); | |
30 | - clear_inode(inode); | |
31 | + struct inode *inode = container_of(head, struct inode, i_rcu); | |
32 | if (S_ISLNK(inode->i_mode)) | |
33 | kfree(inode->i_link); | |
34 | + free_inode_nonrcu(inode); | |
35 | +} | |
36 | + | |
37 | +static void aafs_destroy_inode(struct inode *inode) | |
38 | +{ | |
39 | + call_rcu(&inode->i_rcu, aafs_i_callback); | |
40 | } | |
41 | ||
42 | static const struct super_operations aafs_super_ops = { | |
43 | .statfs = simple_statfs, | |
44 | - .evict_inode = aafs_evict_inode, | |
45 | + .destroy_inode = aafs_destroy_inode, | |
46 | .show_path = aafs_show_path, | |
47 | }; | |
48 | ||
49 | -- | |
50 | 2.20.1 | |
51 |