]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
binfmt_misc: use __free(kfree) in bm_register_write()
authorChristian Brauner <brauner@kernel.org>
Fri, 10 Jul 2026 09:33:22 +0000 (11:33 +0200)
committerChristian Brauner <brauner@kernel.org>
Mon, 3 Aug 2026 08:08:39 +0000 (10:08 +0200)
bm_register_write() has to free the entry it got from create_entry()
on every failure until add_entry() has linked it into the filesystem
and made the inode its owner. Arm the entry with __free(kfree) so the
error branches can simply return and disarm it via
retain_and_null_ptr() once ownership has been handed to the inode.
The interpreter file keeps its manual error cleanup as freeing the
entry would not close it.

No functional change.

Link: https://patch.msgid.link/20260710-work-binfmt_misc-locking-v3-21-a162f7cb58d6@kernel.org
Reviewed-by: Jori Koolstra <jkoolstra@xs4all.nl>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
fs/binfmt_misc.c

index 161d7202d895680f88b061ca9b278453206aa90c..4939e185e24dfd1e8284f70b70b4484b8e619527 100644 (file)
@@ -799,13 +799,12 @@ static int add_entry(struct binfmt_misc_entry *e, struct super_block *sb)
 static ssize_t bm_register_write(struct file *file, const char __user *buffer,
                               size_t count, loff_t *ppos)
 {
-       struct binfmt_misc_entry *e;
+       struct binfmt_misc_entry *e __free(kfree) = NULL;
        struct super_block *sb = file_inode(file)->i_sb;
-       int err = 0;
        struct file *f = NULL;
+       int err;
 
        e = create_entry(buffer, count);
-
        if (IS_ERR(e))
                return PTR_ERR(e);
 
@@ -822,7 +821,6 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer,
                if (IS_ERR(f)) {
                        pr_notice("register: failed to install interpreter file %s\n",
                                 e->interpreter);
-                       kfree(e);
                        return PTR_ERR(f);
                }
                e->interp_file = f;
@@ -834,9 +832,11 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer,
                        exe_file_allow_write_access(f);
                        filp_close(f, NULL);
                }
-               kfree(e);
                return err;
        }
+
+       /* The entry is owned by its inode now. */
+       retain_and_null_ptr(e);
        return count;
 }