From: Trond Myklebust Date: Tue, 21 Sep 2010 20:52:40 +0000 (-0400) Subject: NFS: Fix a use-after-free case in nfs_async_rename() X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=f7732d6573c4f29fc1ca5d384bbf82ddfa115030;p=deliverable%2Flinux.git 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 --- 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, .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); } /**