summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2026-07-10 11:33:22 +0200
committerChristian Brauner <brauner@kernel.org>2026-08-03 10:08:39 +0200
commit8ecfd520eaa46bd79e6b0361f5bb55b144d221b2 (patch)
tree7f28e29d8a0217ea7065b49d45d595a1a710a685
parentf98d6db17e0a4ca5aebdc36ec9c321733f4aa3d8 (diff)
downloadlinux-8ecfd520eaa46bd79e6b0361f5bb55b144d221b2.tar.gz
linux-8ecfd520eaa46bd79e6b0361f5bb55b144d221b2.zip
binfmt_misc: use __free(kfree) in bm_register_write()
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>
-rw-r--r--fs/binfmt_misc.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 161d7202d895..4939e185e24d 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -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;
}