]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
papr-hvpipe: convert papr_hvpipe_dev_create_handle() to FD_PREPARE()
authorChristian Brauner <brauner@kernel.org>
Sun, 23 Nov 2025 16:33:51 +0000 (17:33 +0100)
committerChristian Brauner <brauner@kernel.org>
Fri, 28 Nov 2025 11:42:35 +0000 (12:42 +0100)
Fixes a UAF for src_info as well.

Link: https://patch.msgid.link/20251123-work-fd-prepare-v4-33-b6efa1706cfd@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
arch/powerpc/platforms/pseries/papr-hvpipe.c

index 21a2f447c43fdcccfbfe9e49d8a10f8b9dde268c..dd7b668799d9be00362b0a5e5861028ce3853808 100644 (file)
@@ -479,10 +479,7 @@ static const struct file_operations papr_hvpipe_handle_ops = {
 
 static int papr_hvpipe_dev_create_handle(u32 srcID)
 {
-       struct hvpipe_source_info *src_info;
-       struct file *file;
-       long err;
-       int fd;
+       struct hvpipe_source_info *src_info __free(kfree) = NULL;
 
        spin_lock(&hvpipe_src_list_lock);
        /*
@@ -506,20 +503,13 @@ static int papr_hvpipe_dev_create_handle(u32 srcID)
        src_info->tsk = current;
        init_waitqueue_head(&src_info->recv_wqh);
 
-       fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
-       if (fd < 0) {
-               err = fd;
-               goto free_buf;
-       }
-
-       file = anon_inode_getfile("[papr-hvpipe]",
-                       &papr_hvpipe_handle_ops, (void *)src_info,
-                       O_RDWR);
-       if (IS_ERR(file)) {
-               err = PTR_ERR(file);
-               goto free_fd;
-       }
+       FD_PREPARE(fdf, O_RDONLY | O_CLOEXEC,
+                  anon_inode_getfile("[papr-hvpipe]", &papr_hvpipe_handle_ops,
+                                     (void *)src_info, O_RDWR));
+       if (fdf.err)
+               return fdf.err;
 
+       retain_and_null_ptr(src_info);
        spin_lock(&hvpipe_src_list_lock);
        /*
         * If two processes are executing ioctl() for the same
@@ -528,22 +518,11 @@ static int papr_hvpipe_dev_create_handle(u32 srcID)
         */
        if (hvpipe_find_source(srcID)) {
                spin_unlock(&hvpipe_src_list_lock);
-               err = -EALREADY;
-               goto free_file;
+               return -EALREADY;
        }
        list_add(&src_info->list, &hvpipe_src_list);
        spin_unlock(&hvpipe_src_list_lock);
-
-       fd_install(fd, file);
-       return fd;
-
-free_file:
-       fput(file);
-free_fd:
-       put_unused_fd(fd);
-free_buf:
-       kfree(src_info);
-       return err;
+       return fd_publish(fdf);
 }
 
 /*