Skip to content

Commit

Permalink
NFSv4.0: Fix a use-after-free problem in the asynchronous open()
Browse files Browse the repository at this point in the history
[ Upstream commit 2fdb05dc0931250574f0cb0ebeb5ed8e20f4a889 ]

Yang Erkun reports that when two threads are opening files at the same
time, and are forced to abort before a reply is seen, then the call to
nfs_release_seqid() in nfs4_opendata_free() can result in a
use-after-free of the pointer to the defunct rpc task of the other
thread.
The fix is to ensure that if the RPC call is aborted before the call to
nfs_wait_on_sequence() is complete, then we must call nfs_release_seqid()
in nfs4_open_release() before the rpc_task is freed.

Reported-by: Yang Erkun <[email protected]>
Fixes: 24ac23a ("NFSv4: Convert open() into an asynchronous RPC call")
Reviewed-by: Yang Erkun <[email protected]>
Signed-off-by: Trond Myklebust <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
  • Loading branch information
Trond Myklebust authored and gregkh committed Dec 5, 2024
1 parent 8ff0752 commit 1cfae95
Showing 1 changed file with 5 additions and 3 deletions.
8 changes: 5 additions & 3 deletions fs/nfs/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2379,12 +2379,14 @@ static void nfs4_open_release(void *calldata)
struct nfs4_opendata *data = calldata;
struct nfs4_state *state = NULL;

/* In case of error, no cleanup! */
if (data->rpc_status != 0 || !data->rpc_done) {
nfs_release_seqid(data->o_arg.seqid);
goto out_free;
}
/* If this request hasn't been cancelled, do nothing */
if (!data->cancelled)
goto out_free;
/* In case of error, no cleanup! */
if (data->rpc_status != 0 || !data->rpc_done)
goto out_free;
/* In case we need an open_confirm, no cleanup! */
if (data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM)
goto out_free;
Expand Down

0 comments on commit 1cfae95

Please sign in to comment.