Commit 17ead6c8 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: Fix memory corruption in nfs4_proc_open_confirm

nfs41_wake_and_assign_slot() relies on the task->tk_msg.rpc_argp and
task->tk_msg.rpc_resp always pointing to the session sequence arguments.

nfs4_proc_open_confirm tries to pull a fast one by reusing the open
sequence structure, thus causing corruption of the NFSv4 slot table.

Cc: stable@vger.kernel.org # 3.12+
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 8a1f006a
...@@ -1620,15 +1620,15 @@ static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata) ...@@ -1620,15 +1620,15 @@ static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata)
{ {
struct nfs4_opendata *data = calldata; struct nfs4_opendata *data = calldata;
nfs40_setup_sequence(data->o_arg.server, &data->o_arg.seq_args, nfs40_setup_sequence(data->o_arg.server, &data->c_arg.seq_args,
&data->o_res.seq_res, task); &data->c_res.seq_res, task);
} }
static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
{ {
struct nfs4_opendata *data = calldata; struct nfs4_opendata *data = calldata;
nfs40_sequence_done(task, &data->o_res.seq_res); nfs40_sequence_done(task, &data->c_res.seq_res);
data->rpc_status = task->tk_status; data->rpc_status = task->tk_status;
if (data->rpc_status == 0) { if (data->rpc_status == 0) {
...@@ -1686,7 +1686,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data) ...@@ -1686,7 +1686,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
}; };
int status; int status;
nfs4_init_sequence(&data->o_arg.seq_args, &data->o_res.seq_res, 1); nfs4_init_sequence(&data->c_arg.seq_args, &data->c_res.seq_res, 1);
kref_get(&data->kref); kref_get(&data->kref);
data->rpc_done = 0; data->rpc_done = 0;
data->rpc_status = 0; data->rpc_status = 0;
......
...@@ -379,12 +379,14 @@ struct nfs_openres { ...@@ -379,12 +379,14 @@ struct nfs_openres {
* Arguments to the open_confirm call. * Arguments to the open_confirm call.
*/ */
struct nfs_open_confirmargs { struct nfs_open_confirmargs {
struct nfs4_sequence_args seq_args;
const struct nfs_fh * fh; const struct nfs_fh * fh;
nfs4_stateid * stateid; nfs4_stateid * stateid;
struct nfs_seqid * seqid; struct nfs_seqid * seqid;
}; };
struct nfs_open_confirmres { struct nfs_open_confirmres {
struct nfs4_sequence_res seq_res;
nfs4_stateid stateid; nfs4_stateid stateid;
struct nfs_seqid * seqid; struct nfs_seqid * seqid;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment