Skip to content

Commit fd40559

Browse files
trondmypdamschuma-ntap
authored andcommitted
NFSv4: Fix EXCHANGE_ID corrupt verifier issue
The verifier is allocated on the stack, but the EXCHANGE_ID RPC call was changed to be asynchronous by commit 8d89bd7. If we interrrupt the call to rpc_wait_for_completion_task(), we can therefore end up transmitting random stack contents in lieu of the verifier. Fixes: 8d89bd7 ("NFS setup async exchange_id") Cc: stable@vger.kernel.org # v4.9+ Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent b7dbcc0 commit fd40559

File tree

3 files changed

+6
-9
lines changed

3 files changed

+6
-9
lines changed

fs/nfs/nfs4proc.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7460,7 +7460,7 @@ static void nfs4_exchange_id_done(struct rpc_task *task, void *data)
74607460
cdata->res.server_scope = NULL;
74617461
}
74627462
/* Save the EXCHANGE_ID verifier session trunk tests */
7463-
memcpy(clp->cl_confirm.data, cdata->args.verifier->data,
7463+
memcpy(clp->cl_confirm.data, cdata->args.verifier.data,
74647464
sizeof(clp->cl_confirm.data));
74657465
}
74667466
out:
@@ -7497,7 +7497,6 @@ static const struct rpc_call_ops nfs4_exchange_id_call_ops = {
74977497
static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
74987498
u32 sp4_how, struct rpc_xprt *xprt)
74997499
{
7500-
nfs4_verifier verifier;
75017500
struct rpc_message msg = {
75027501
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_EXCHANGE_ID],
75037502
.rpc_cred = cred,
@@ -7521,8 +7520,7 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
75217520
return -ENOMEM;
75227521
}
75237522

7524-
if (!xprt)
7525-
nfs4_init_boot_verifier(clp, &verifier);
7523+
nfs4_init_boot_verifier(clp, &calldata->args.verifier);
75267524

75277525
status = nfs4_init_uniform_client_string(clp);
75287526
if (status)
@@ -7563,9 +7561,8 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
75637561
task_setup_data.rpc_xprt = xprt;
75647562
task_setup_data.flags =
75657563
RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC;
7566-
calldata->args.verifier = &clp->cl_confirm;
7567-
} else {
7568-
calldata->args.verifier = &verifier;
7564+
memcpy(calldata->args.verifier.data, clp->cl_confirm.data,
7565+
sizeof(calldata->args.verifier.data));
75697566
}
75707567
calldata->args.client = clp;
75717568
#ifdef CONFIG_NFS_V4_1_MIGRATION

fs/nfs/nfs4xdr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,7 @@ static void encode_exchange_id(struct xdr_stream *xdr,
17851785
int len = 0;
17861786

17871787
encode_op_hdr(xdr, OP_EXCHANGE_ID, decode_exchange_id_maxsz, hdr);
1788-
encode_nfs4_verifier(xdr, args->verifier);
1788+
encode_nfs4_verifier(xdr, &args->verifier);
17891789

17901790
encode_string(xdr, strlen(args->client->cl_owner_id),
17911791
args->client->cl_owner_id);

include/linux/nfs_xdr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,7 @@ struct nfs41_state_protection {
12351235

12361236
struct nfs41_exchange_id_args {
12371237
struct nfs_client *client;
1238-
nfs4_verifier *verifier;
1238+
nfs4_verifier verifier;
12391239
u32 flags;
12401240
struct nfs41_state_protection state_protect;
12411241
};

0 commit comments

Comments
 (0)