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 | |
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')
-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 698b3e6367ff..47530aacebfd 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, | |||
426 | .rpc_client = NFS_CLIENT(old_dir), | 426 | .rpc_client = NFS_CLIENT(old_dir), |
427 | .flags = RPC_TASK_ASYNC, | 427 | .flags = RPC_TASK_ASYNC, |
428 | }; | 428 | }; |
429 | struct rpc_task *task; | ||
430 | 429 | ||
431 | data = kmalloc(sizeof(*data), GFP_KERNEL); | 430 | data = kmalloc(sizeof(*data), GFP_KERNEL); |
432 | if (data == NULL) | 431 | if (data == NULL) |
@@ -435,7 +434,7 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir, | |||
435 | 434 | ||
436 | data->cred = rpc_lookup_cred(); | 435 | data->cred = rpc_lookup_cred(); |
437 | if (IS_ERR(data->cred)) { | 436 | if (IS_ERR(data->cred)) { |
438 | task = (struct rpc_task *)data->cred; | 437 | struct rpc_task *task = ERR_CAST(data->cred); |
439 | kfree(data); | 438 | kfree(data); |
440 | return task; | 439 | return task; |
441 | } | 440 | } |
@@ -468,11 +467,7 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir, | |||
468 | 467 | ||
469 | NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dir); | 468 | NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dir); |
470 | 469 | ||
471 | task = rpc_run_task(&task_setup_data); | 470 | return rpc_run_task(&task_setup_data); |
472 | if (IS_ERR(task)) | ||
473 | nfs_async_rename_release(data); | ||
474 | |||
475 | return task; | ||
476 | } | 471 | } |
477 | 472 | ||
478 | /** | 473 | /** |