[PATCH] rust_binderfs: fix minor number leak on binder-control creation failure

From: Adhyansh Verma

Date: Mon Nov 02 2026 - 12:40:40 EST


In binderfs_binder_ctl_create(), a minor number is reserved using
ida_alloc_max(). If d_alloc_name() subsequently fails (e.g. under memory
pressure), the function jumps to the error path.

However, the cleanup path only calls kfree(device) and iput(inode).
Because inode->i_private has not yet been set to device, the eviction
handler binderfs_evict_inode() returns early without freeing the minor
number. Consequently, the reserved minor number is permanently leaked
from the global binderfs_minors IDA.

Fix this by introducing proper error unwind labels so that the allocated
minor number is released via ida_free() under binderfs_minors_mutex if
dentry allocation fails.

Fixes: eafedbc7c050 ("rust_binder: add Rust Binder driver")
Signed-off-by: Adhyansh Verma <adhyanshverma2010@xxxxxxxxx>
---
drivers/android/binder/rust_binderfs.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/android/binder/rust_binderfs.c b/drivers/android/binder/rust_binderfs.c
index 5f020226720d..3f7ff0fdbdb9 100644
--- a/drivers/android/binder/rust_binderfs.c
+++ b/drivers/android/binder/rust_binderfs.c
@@ -400,7 +400,7 @@ static int binderfs_binder_ctl_create(struct super_block *sb)
ret = -ENOMEM;
inode = new_inode(sb);
if (!inode)
- goto out;
+ goto out_device;

/* Reserve a new minor number for the new device. */
mutex_lock(&binderfs_minors_mutex);
@@ -411,7 +411,7 @@ static int binderfs_binder_ctl_create(struct super_block *sb)
mutex_unlock(&binderfs_minors_mutex);
if (minor < 0) {
ret = minor;
- goto out;
+ goto out_inode;
}

inode->i_ino = SECOND_INODE;
@@ -427,7 +427,7 @@ static int binderfs_binder_ctl_create(struct super_block *sb)

dentry = d_alloc_name(root, "binder-control");
if (!dentry)
- goto out;
+ goto out_minor;

inode->i_private = device;
info->control_dentry = dentry;
@@ -436,9 +436,14 @@ static int binderfs_binder_ctl_create(struct super_block *sb)

return 0;

-out:
- kfree(device);
+out_minor:
+ mutex_lock(&binderfs_minors_mutex);
+ ida_free(&binderfs_minors, minor);
+ mutex_unlock(&binderfs_minors_mutex);
+out_inode:
iput(inode);
+out_device:
+ kfree(device);

return ret;
}
--
2.56.0