diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2023-09-27 22:11:26 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2024-02-25 02:10:32 -0500 |
commit | c1b967d03c5d570ed7b90a88031fa2af34bf5b20 (patch) | |
tree | 230fde52c95cc00c8d08bdc2a49d119ccd79a325 /include | |
parent | 10a973fc4fb22390a8d362dd3265ec2c9a81d84c (diff) |
nfs: fix UAF on pathwalk running into umount
NFS ->d_revalidate(), ->permission() and ->get_link() need to access
some parts of nfs_server when called in RCU mode:
server->flags
server->caps
*(server->io_stats)
and, worst of all, call
server->nfs_client->rpc_ops->have_delegation
(the last one - as NFS_PROTO(inode)->have_delegation()). We really
don't want to RCU-delay the entire nfs_free_server() (it would have
to be done with schedule_work() from RCU callback, since it can't
be made to run from interrupt context), but actual freeing of
nfs_server and ->io_stats can be done via call_rcu() just fine.
nfs_client part is handled simply by making nfs_free_client() use
kfree_rcu().
Acked-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/nfs_fs_sb.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index cd797e00fe35..92de074e63b9 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -124,6 +124,7 @@ struct nfs_client { char cl_ipaddr[48]; struct net *cl_net; struct list_head pending_cb_stateids; + struct rcu_head rcu; }; /* @@ -265,6 +266,7 @@ struct nfs_server { const struct cred *cred; bool has_sec_mnt_opts; struct kobject kobj; + struct rcu_head rcu; }; /* Server capabilities */ |