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>
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);
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;
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;
}