]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Aug 2020 12:10:48 +0000 (14:10 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Aug 2020 12:10:48 +0000 (14:10 +0200)
added patches:
binder-prevent-context-manager-from-incrementing-ref-0.patch

queue-4.4/binder-prevent-context-manager-from-incrementing-ref-0.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/binder-prevent-context-manager-from-incrementing-ref-0.patch b/queue-4.4/binder-prevent-context-manager-from-incrementing-ref-0.patch
new file mode 100644 (file)
index 0000000..cbe19d0
--- /dev/null
@@ -0,0 +1,86 @@
+From 4b836a1426cb0f1ef2a6e211d7e553221594f8fc Mon Sep 17 00:00:00 2001
+From: Jann Horn <jannh@google.com>
+Date: Mon, 27 Jul 2020 14:04:24 +0200
+Subject: binder: Prevent context manager from incrementing ref 0
+
+From: Jann Horn <jannh@google.com>
+
+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@vger.kernel.org
+Fixes: 457b9a6f09f0 ("Staging: android: add binder driver")
+Acked-by: Todd Kjos <tkjos@google.com>
+Signed-off-by: Jann Horn <jannh@google.com>
+Reviewed-by: Martijn Coenen <maco@android.com>
+Link: https://lore.kernel.org/r/20200727120424.1627555-1-jannh@google.com
+[manual backport: remove fine-grained locking and error reporting that
+                  don't exist in <=4.9]
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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) {
index 7f04694f5d776f57e441eaf768ed10f2fa699a35..d1484ae201f592c4f1370e14bbbec9869ca27825 100644 (file)
@@ -43,3 +43,4 @@ cfg80211-check-vendor-command-doit-pointer-before-us.patch
 igb-reinit_locked-should-be-called-with-rtnl_lock.patch
 atm-fix-atm_dev-refcnt-leaks-in-atmtcp_remove_persis.patch
 tools-lib-traceevent-fix-memory-leak-in-process_dyna.patch
+binder-prevent-context-manager-from-incrementing-ref-0.patch