Commit f7732d65 authored by Trond Myklebust's avatar Trond Myklebust

NFS: Fix a use-after-free case in nfs_async_rename()

The call to nfs_async_rename_release() after rpc_run_task() is incorrect.
The rpc_run_task() is always guaranteed to call the ->rpc_release() method.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent d3d4152a
...@@ -426,7 +426,6 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir, ...@@ -426,7 +426,6 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
.rpc_client = NFS_CLIENT(old_dir), .rpc_client = NFS_CLIENT(old_dir),
.flags = RPC_TASK_ASYNC, .flags = RPC_TASK_ASYNC,
}; };
struct rpc_task *task;
data = kmalloc(sizeof(*data), GFP_KERNEL); data = kmalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL) if (data == NULL)
...@@ -435,7 +434,7 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir, ...@@ -435,7 +434,7 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
data->cred = rpc_lookup_cred(); data->cred = rpc_lookup_cred();
if (IS_ERR(data->cred)) { if (IS_ERR(data->cred)) {
task = (struct rpc_task *)data->cred; struct rpc_task *task = ERR_CAST(data->cred);
kfree(data); kfree(data);
return task; return task;
} }
...@@ -468,11 +467,7 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir, ...@@ -468,11 +467,7 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dir); NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dir);
task = rpc_run_task(&task_setup_data); return rpc_run_task(&task_setup_data);
if (IS_ERR(task))
nfs_async_rename_release(data);
return task;
} }
/** /**
......
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