diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-09-21 16:52:40 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-09-21 16:52:40 -0400 |
commit | f7732d6573c4f29fc1ca5d384bbf82ddfa115030 (patch) | |
tree | e0f94b8406908e4e3081afa436a2aa8eed06773d /fs/nfs/unlink.c | |
parent | d3d4152a5d59af9e13a73efa9e9c24383fbe307f (diff) |
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: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/unlink.c')
-rw-r--r-- | fs/nfs/unlink.c | 9 |
1 files changed, 2 insertions, 7 deletions
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index 698b3e6367f..47530aacebf 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c @@ -426,7 +426,6 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir, .rpc_client = NFS_CLIENT(old_dir), .flags = RPC_TASK_ASYNC, }; - struct rpc_task *task; data = kmalloc(sizeof(*data), GFP_KERNEL); if (data == NULL) @@ -435,7 +434,7 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir, data->cred = rpc_lookup_cred(); if (IS_ERR(data->cred)) { - task = (struct rpc_task *)data->cred; + struct rpc_task *task = ERR_CAST(data->cred); kfree(data); return task; } @@ -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); - task = rpc_run_task(&task_setup_data); - if (IS_ERR(task)) - nfs_async_rename_release(data); - - return task; + return rpc_run_task(&task_setup_data); } /** |