NFS: Fix a use-after-free case in nfs_async_rename()
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 21 Sep 2010 20:52:40 +0000 (16:52 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 21 Sep 2010 20:52:40 +0000 (16:52 -0400)
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>
fs/nfs/unlink.c

index 698b3e6367ff7ec4c6f6e10f2f66e1d7327defb8..47530aacebfdae06726bc667c4b7d819e04c2758 100644 (file)
@@ -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);
 }
 
 /**