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: 8d89bd70bc
("NFS setup async exchange_id")
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Cc: stable@vger.kernel.org # 4.9
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
05fae7bbc2
commit
63513232f8
|
@ -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 @@ out_server_owner:
|
|||
kfree(calldata->res.server_owner);
|
||||
out_calldata:
|
||||
kfree(calldata);
|
||||
nfs_put_client(clp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue