summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2019-04-02 15:17:34 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2019-04-09 19:18:19 -0400
commitce285c267a003acbf607f3540ff71287f82e5282 (patch)
treee1fc114f3e1246fc819452ce1254e0df777f12bd
parent5467a68cbf6884c9a9d91e2a89140afb1839c835 (diff)
autofs: fix use-after-free in lockless ->d_manage()
autofs_d_release() can overlap with lockless ->d_manage(), ending up with autofs_dentry_ino() freed under the latter. Make freeing autofs_info instances RCU-delayed... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/autofs/autofs_i.h1
-rw-r--r--fs/autofs/inode.c2
2 files changed, 2 insertions, 1 deletions
diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h
index 70c132acdab1..e1091312abe1 100644
--- a/fs/autofs/autofs_i.h
+++ b/fs/autofs/autofs_i.h
@@ -71,6 +71,7 @@ struct autofs_info {
kuid_t uid;
kgid_t gid;
+ struct rcu_head rcu;
};
#define AUTOFS_INF_EXPIRING (1<<0) /* dentry in the process of expiring */
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
index 80597b88718b..fb0225f21c12 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -36,7 +36,7 @@ void autofs_clean_ino(struct autofs_info *ino)
void autofs_free_ino(struct autofs_info *ino)
{
- kfree(ino);
+ kfree_rcu(ino, rcu);
}
void autofs_kill_sb(struct super_block *sb)