[PATCH 2/3] NFSD: Prevent post-shutdown use-after-free in NFSD_CMD_UNLOCK_FILESYSTEM
Chuck Lever <[email protected]>
| Newsgroups | gmane.linux.nfs |
|---|---|
| Message-ID | <[email protected]> |
The NFSD_CMD_UNLOCK_FILESYSTEM netlink command runs
nfsd4_cancel_copy_by_sb() before nfsd_mutex is held and before
nn->nfsd_serv is confirmed set, the same pre-mutex ordering the procfs
unlock_filesystem path carried. Once nfsd has shut down,
nfs4_state_destroy_net() has freed nn->conf_id_hashtbl but left the
pointer intact, so the cancel helper iterates freed slab memory as an
array of struct list_head and then dereferences a bogus nfs4_client
when it takes clp->async_lock. A local administrator holding
CAP_SYS_ADMIN can reach this use-after-free by stopping the server and
then issuing the command.
Move the async COPY cancel into the nfsd_mutex section, after
nn->nfsd_serv is confirmed, so every NFSv4 state-table walker on this
path observes a running server. Async copies exist only while the
server runs, so gating the cancel on nn->nfsd_serv loses nothing.
Fixes: 327c5168eff2 ("NFSD: Add NFSD_CMD_UNLOCK_FILESYSTEM netlink command")
Signed-off-by: Chuck Lever <[email protected]>
---
fs/nfsd/nfsctl.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 29d68abfa5c8..f1ecbb13f642 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -2368,14 +2368,15 @@ int nfsd_nl_unlock_filesystem_doit(struct sk_buff *skb,
if (error)
return error;
- nfsd4_cancel_copy_by_sb(net, path.dentry->d_sb);
error = nlmsvc_unlock_all_by_sb(path.dentry->d_sb);
mutex_lock(&nfsd_mutex);
- if (nn->nfsd_serv)
+ if (nn->nfsd_serv) {
+ nfsd4_cancel_copy_by_sb(net, path.dentry->d_sb);
nfsd4_revoke_states(nn, path.dentry->d_sb);
- else
+ } else {
error = -EINVAL;
+ }
mutex_unlock(&nfsd_mutex);
path_put(&path);
--
2.54.0