This is a note to let you know that I've just added the patch titled binder: Prevent context manager from incrementing ref 0 to the 4.4-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: binder-prevent-context-manager-from-incrementing-ref-0.patch and it can be found in the queue-4.4 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 4b836a1426cb0f1ef2a6e211d7e553221594f8fc Mon Sep 17 00:00:00 2001 From: Jann Horn <jannh@xxxxxxxxxx> Date: Mon, 27 Jul 2020 14:04:24 +0200 Subject: binder: Prevent context manager from incrementing ref 0 From: Jann Horn <jannh@xxxxxxxxxx> commit 4b836a1426cb0f1ef2a6e211d7e553221594f8fc 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: stable@xxxxxxxxxxxxxxx Fixes: 457b9a6f09f0 ("Staging: android: add binder driver") Acked-by: Todd Kjos <tkjos@xxxxxxxxxx> Signed-off-by: Jann Horn <jannh@xxxxxxxxxx> Reviewed-by: Martijn Coenen <maco@xxxxxxxxxxx> Link: https://lore.kernel.org/r/20200727120424.1627555-1-jannh@xxxxxxxxxx [manual backport: remove fine-grained locking and error reporting that don't exist in <=4.9] Signed-off-by: Jann Horn <jannh@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/android/binder.c | 9 +++++++++ 1 file changed, 9 insertions(+) --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -1415,6 +1415,10 @@ static void binder_transaction(struct bi return_error = BR_DEAD_REPLY; goto err_dead_binder; } + if (WARN_ON(proc == target_proc)) { + return_error = BR_FAILED_REPLY; + goto err_invalid_target_handle; + } if (security_binder_transaction(proc->tsk, target_proc->tsk) < 0) { return_error = BR_FAILED_REPLY; @@ -1812,6 +1816,11 @@ static int binder_thread_write(struct bi ptr += sizeof(uint32_t); if (target == 0 && binder_context_mgr_node && (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) { + if (binder_context_mgr_node->proc == proc) { + binder_user_error("%d:%d context manager tried to acquire desc 0\n", + proc->pid, thread->pid); + return -EINVAL; + } ref = binder_get_ref_for_node(proc, binder_context_mgr_node); if (ref->desc != target) { Patches currently in stable-queue which might be from jannh@xxxxxxxxxx are queue-4.4/binder-prevent-context-manager-from-incrementing-ref-0.patch