Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7e63a10 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4: Fix another nfs4_sequence corruptor



nfs4_release_lockowner needs to set the rpc_message reply to point to
the nfs4_sequence_res in order to avoid another Oopsable situation
in nfs41_assign_slot.

Fixes: fbd4bfd1 (NFS: Add nfs4_sequence calls for RELEASE_LOCKOWNER)
Cc: stable@vger.kernel.org # 3.12+
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 146d70ca
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -5828,8 +5828,7 @@ struct nfs_release_lockowner_data {
	struct nfs4_lock_state *lsp;
	struct nfs_server *server;
	struct nfs_release_lockowner_args args;
	struct nfs4_sequence_args seq_args;
	struct nfs4_sequence_res seq_res;
	struct nfs_release_lockowner_res res;
	unsigned long timestamp;
};

@@ -5837,7 +5836,7 @@ static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata
{
	struct nfs_release_lockowner_data *data = calldata;
	nfs40_setup_sequence(data->server,
				&data->seq_args, &data->seq_res, task);
				&data->args.seq_args, &data->res.seq_res, task);
	data->timestamp = jiffies;
}

@@ -5846,7 +5845,7 @@ static void nfs4_release_lockowner_done(struct rpc_task *task, void *calldata)
	struct nfs_release_lockowner_data *data = calldata;
	struct nfs_server *server = data->server;

	nfs40_sequence_done(task, &data->seq_res);
	nfs40_sequence_done(task, &data->res.seq_res);

	switch (task->tk_status) {
	case 0:
@@ -5887,7 +5886,6 @@ static int nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_st
	data = kmalloc(sizeof(*data), GFP_NOFS);
	if (!data)
		return -ENOMEM;
	nfs4_init_sequence(&data->seq_args, &data->seq_res, 0);
	data->lsp = lsp;
	data->server = server;
	data->args.lock_owner.clientid = server->nfs_client->cl_clientid;
@@ -5895,6 +5893,8 @@ static int nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_st
	data->args.lock_owner.s_dev = server->s_dev;

	msg.rpc_argp = &data->args;
	msg.rpc_resp = &data->res;
	nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0);
	rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data);
	return 0;
}
+5 −0
Original line number Diff line number Diff line
@@ -467,9 +467,14 @@ struct nfs_lockt_res {
};

struct nfs_release_lockowner_args {
	struct nfs4_sequence_args	seq_args;
	struct nfs_lowner	lock_owner;
};

struct nfs_release_lockowner_res {
	struct nfs4_sequence_res	seq_res;
};

struct nfs4_delegreturnargs {
	struct nfs4_sequence_args	seq_args;
	const struct nfs_fh *fhandle;