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

Commit 63513232 authored by Olga Kornievskaia's avatar Olga Kornievskaia Committed by Anna Schumaker
Browse files

NFS prevent double free in async nfs4_exchange_id



Since rpc_task is async, the release function should be called which
will free the impl_id, scope, and owner.

Trond pointed at 2 more problems:
-- use of client pointer after free in the nfs4_exchangeid_release() function
-- cl_count mismatch if rpc_run_task() isn't run

Fixes: 8d89bd70 ("NFS setup async exchange_id")
Signed-off-by: default avatarOlga Kornievskaia <kolga@netapp.com>
Cc: stable@vger.kernel.org # 4.9
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 05fae7bb
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -7425,11 +7425,11 @@ static void nfs4_exchange_id_release(void *data)
	struct nfs41_exchange_id_data *cdata =
					(struct nfs41_exchange_id_data *)data;

	nfs_put_client(cdata->args.client);
	if (cdata->xprt) {
		xprt_put(cdata->xprt);
		rpc_clnt_xprt_switch_put(cdata->args.client->cl_rpcclient);
	}
	nfs_put_client(cdata->args.client);
	kfree(cdata->res.impl_id);
	kfree(cdata->res.server_scope);
	kfree(cdata->res.server_owner);
@@ -7536,10 +7536,8 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
	task_setup_data.callback_data = calldata;

	task = rpc_run_task(&task_setup_data);
	if (IS_ERR(task)) {
	status = PTR_ERR(task);
		goto out_impl_id;
	}
	if (IS_ERR(task))
		return PTR_ERR(task);

	if (!xprt) {
		status = rpc_wait_for_completion_task(task);
@@ -7567,6 +7565,7 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
	kfree(calldata->res.server_owner);
out_calldata:
	kfree(calldata);
	nfs_put_client(clp);
	goto out;
}