FAILED: patch "[PATCH] binder: Prevent context manager from incrementing ref 0" failed to apply to 4.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 4b836a1426cb0f1ef2a6e211d7e553221594f8fc Mon Sep 17 00:00:00 2001
From: Jann Horn <[email protected]>
Date: Mon, 27 Jul 2020 14:04:24 +0200
Subject: [PATCH] binder: Prevent context manager from incrementing ref 0
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.
drivers/android/binder.c +14 -1
@@ -2982,6 +2982,12 @@ static void binder_transaction(struct binder_proc *proc, goto err_dead_binder; } e->to_node = target_node->debug_id; +if (WARN_ON (proc == target_proc)) { + return_error =BR_FAILED_REPLY ; + return_error_param = -EINVAL ; + return_error_line = __LINE__; + goto err_invalid_target_handle; + }if (security_binder_transaction (proc->tsk, target_proc->tsk) <0 ) { return_error =BR_FAILED_REPLY ;
@@ -3635,10 +3641,17 @@ static int binder_thread_write(struct binder_proc *proc,struct binder_node *ctx_mgr_node;mutex_lock (&context->context_mgr_node_lock); ctx_mgr_node = context->binder_context_mgr_node; -if (ctx_mgr_node) +if (ctx_mgr_node) { +if (ctx_mgr_node->proc == proc) { +binder_user_error ("%d:%d context manager tried to acquire desc 0\n" , + proc->pid, thread->pid); +mutex_unlock (&context->context_mgr_node_lock); +return -EINVAL ; + } ret =binder_inc_ref_for_node ( proc, ctx_mgr_node, strong,NULL , &rdata); + }mutex_unlock (&context->context_mgr_node_lock); }if (ret)