Skip to content

Commit 1427acb

Browse files
thejhgregkh
authored andcommitted
binder: Prevent context manager from incrementing ref 0
commit 4b836a1 upstream. Binder is designed such that a binder_proc never has references to itself. If this rule is violated, memory corruption can occur when a process sends a transaction to itself; see e.g. <https://syzkaller.appspot.com/bug?extid=09e05aba06723a94d43d>. There is a remaining edgecase through which such a transaction-to-self can still occur from the context of a task with BINDER_SET_CONTEXT_MGR access: - task A opens /dev/binder twice, creating binder_proc instances P1 and P2 - P1 becomes context manager - P2 calls ACQUIRE on the magic handle 0, allocating index 0 in its handle table - P1 dies (by closing the /dev/binder fd and waiting a bit) - P2 becomes context manager - P2 calls ACQUIRE on the magic handle 0, allocating index 1 in its handle table [this triggers a warning: "binder: 1974:1974 tried to acquire reference to desc 0, got 1 instead"] - task B opens /dev/binder once, creating binder_proc instance P3 - P3 calls P2 (via magic handle 0) with (void*)1 as argument (two-way transaction) - P2 receives the handle and uses it to call P3 (two-way transaction) - P3 calls P2 (via magic handle 0) (two-way transaction) - P2 calls P2 (via handle 1) (two-way transaction) And then, if P2 does *NOT* accept the incoming transaction work, but instead closes the binder fd, we get a crash. Solve it by preventing the context manager from using ACQUIRE on ref 0. There shouldn't be any legitimate reason for the context manager to do that. Additionally, print a warning if someone manages to find another way to trigger a transaction-to-self bug in the future. Cc: [email protected] Fixes: 457b9a6 ("Staging: android: add binder driver") Acked-by: Todd Kjos <[email protected]> Signed-off-by: Jann Horn <[email protected]> Reviewed-by: Martijn Coenen <[email protected]> Link: https://lore.kernel.org/r/[email protected] [manual backport: remove fine-grained locking and error reporting that don't exist in <=4.9] Signed-off-by: Jann Horn <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 419d10a commit 1427acb

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

drivers/android/binder.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,10 @@ static void binder_transaction(struct binder_proc *proc,
14271427
return_error = BR_DEAD_REPLY;
14281428
goto err_dead_binder;
14291429
}
1430+
if (WARN_ON(proc == target_proc)) {
1431+
return_error = BR_FAILED_REPLY;
1432+
goto err_invalid_target_handle;
1433+
}
14301434
if (security_binder_transaction(proc->tsk,
14311435
target_proc->tsk) < 0) {
14321436
return_error = BR_FAILED_REPLY;
@@ -1830,6 +1834,11 @@ static int binder_thread_write(struct binder_proc *proc,
18301834
ptr += sizeof(uint32_t);
18311835
if (target == 0 && binder_context_mgr_node &&
18321836
(cmd == BC_INCREFS || cmd == BC_ACQUIRE)) {
1837+
if (binder_context_mgr_node->proc == proc) {
1838+
binder_user_error("%d:%d context manager tried to acquire desc 0\n",
1839+
proc->pid, thread->pid);
1840+
return -EINVAL;
1841+
}
18331842
ref = binder_get_ref_for_node(proc,
18341843
binder_context_mgr_node);
18351844
if (ref->desc != target) {

0 commit comments

Comments
 (0)