[PATCH 1/4] binder: cap BINDER_SET_MAX_THREADS at RLIMIT_NPROC

From: Yunseong Kim

Date: Wed Jun 03 2026 - 14:04:19 EST


BINDER_SET_MAX_THREADS accepts any u32 value from userspace without
validation. An unprivileged process can set max_threads to 0xFFFFFFFF,
allowing unlimited binder thread spawning via BR_SPAWN_LOOPER. This
bypasses RLIMIT_NPROC because binder thread pool management happens
in kernel context, and exhausts system memory leading to OOM.

Cap max_threads at the calling task's RLIMIT_NPROC, following the same
pattern used by io_uring (io-wq.c) to limit its worker thread count.
This ensures binder respects the per-user resource limits set by the
system administrator.

kcov-dataflow tracking (before):
ENTRY binder_ioctl(cmd=BINDER_SET_MAX_THREADS, arg=0x7ffc...)
ENTRY set_max_threads(max=0xffffffff)
RET set_max_threads() = 0 ← accepted, no validation
RET binder_ioctl() = 0

kcov-dataflow tracking (after):
ENTRY binder_ioctl(cmd=BINDER_SET_MAX_THREADS, arg=0x7ffc...)
ENTRY set_max_threads(max=0xffffffff)
RET set_max_threads() = -EINVAL ← rejected, exceeds RLIMIT_NPROC
RET binder_ioctl() = -EINVAL

Reproduction:
$ ulimit -u 50
$ ./To-Ulimit-and-Beyond # uid=65534, creates 300+ threads bypassing limit

Fixes: 457b9a6f09f0 ("Staging: android: add binder driver")
Link: https://lore.kernel.org/all/20260603-kcov-dataflow-next-20260603-v2-0-fee0939de2c4@xxxxxxxx/
Signed-off-by: Yunseong Kim <yunseong.kim@xxxxxxxx>
---
drivers/android/binder.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index ec0ab4f28530..0f3fc293cdf0 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -5801,6 +5801,10 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
ret = -EINVAL;
goto err;
}
+ if (max_threads > rlimit(RLIMIT_NPROC)) {
+ ret = -EINVAL;
+ goto err;
+ }
binder_inner_proc_lock(proc);
proc->max_threads = max_threads;
binder_inner_proc_unlock(proc);

--
2.43.0