]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 6 Oct 2019 07:32:47 +0000 (09:32 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 6 Oct 2019 07:32:47 +0000 (09:32 +0200)
added patches:
android-binder-remove-waitqueue-when-thread-exits.patch
android-binder-synchronize_rcu-when-using-pollfree.patch

queue-4.4/android-binder-remove-waitqueue-when-thread-exits.patch [new file with mode: 0644]
queue-4.4/android-binder-synchronize_rcu-when-using-pollfree.patch [new file with mode: 0644]
queue-4.4/series [new file with mode: 0644]
queue-4.9/series [new file with mode: 0644]

diff --git a/queue-4.4/android-binder-remove-waitqueue-when-thread-exits.patch b/queue-4.4/android-binder-remove-waitqueue-when-thread-exits.patch
new file mode 100644 (file)
index 0000000..f7dc9a5
--- /dev/null
@@ -0,0 +1,70 @@
+From f5cb779ba16334b45ba8946d6bfa6d9834d1527f Mon Sep 17 00:00:00 2001
+From: Martijn Coenen <maco@android.com>
+Date: Fri, 5 Jan 2018 11:27:07 +0100
+Subject: ANDROID: binder: remove waitqueue when thread exits.
+
+From: Martijn Coenen <maco@android.com>
+
+commit f5cb779ba16334b45ba8946d6bfa6d9834d1527f upstream.
+
+binder_poll() passes the thread->wait waitqueue that
+can be slept on for work. When a thread that uses
+epoll explicitly exits using BINDER_THREAD_EXIT,
+the waitqueue is freed, but it is never removed
+from the corresponding epoll data structure. When
+the process subsequently exits, the epoll cleanup
+code tries to access the waitlist, which results in
+a use-after-free.
+
+Prevent this by using POLLFREE when the thread exits.
+
+Signed-off-by: Martijn Coenen <maco@android.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Cc: stable <stable@vger.kernel.org> # 4.14
+[backport BINDER_LOOPER_STATE_POLL logic as well]
+Signed-off-by: Mattias Nissler <mnissler@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/android/binder.c |   17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+--- a/drivers/android/binder.c
++++ b/drivers/android/binder.c
+@@ -334,7 +334,8 @@ enum {
+       BINDER_LOOPER_STATE_EXITED      = 0x04,
+       BINDER_LOOPER_STATE_INVALID     = 0x08,
+       BINDER_LOOPER_STATE_WAITING     = 0x10,
+-      BINDER_LOOPER_STATE_NEED_RETURN = 0x20
++      BINDER_LOOPER_STATE_NEED_RETURN = 0x20,
++      BINDER_LOOPER_STATE_POLL        = 0x40,
+ };
+ struct binder_thread {
+@@ -2610,6 +2611,18 @@ static int binder_free_thread(struct bin
+               } else
+                       BUG();
+       }
++
++      /*
++       * If this thread used poll, make sure we remove the waitqueue
++       * from any epoll data structures holding it with POLLFREE.
++       * waitqueue_active() is safe to use here because we're holding
++       * the inner lock.
++       */
++      if ((thread->looper & BINDER_LOOPER_STATE_POLL) &&
++          waitqueue_active(&thread->wait)) {
++              wake_up_poll(&thread->wait, POLLHUP | POLLFREE);
++      }
++
+       if (send_reply)
+               binder_send_failed_reply(send_reply, BR_DEAD_REPLY);
+       binder_release_work(&thread->todo);
+@@ -2633,6 +2646,8 @@ static unsigned int binder_poll(struct f
+               return POLLERR;
+       }
++      thread->looper |= BINDER_LOOPER_STATE_POLL;
++
+       wait_for_proc_work = thread->transaction_stack == NULL &&
+               list_empty(&thread->todo) && thread->return_error == BR_OK;
diff --git a/queue-4.4/android-binder-synchronize_rcu-when-using-pollfree.patch b/queue-4.4/android-binder-synchronize_rcu-when-using-pollfree.patch
new file mode 100644 (file)
index 0000000..66a9712
--- /dev/null
@@ -0,0 +1,39 @@
+From 5eeb2ca02a2f6084fc57ae5c244a38baab07033a Mon Sep 17 00:00:00 2001
+From: Martijn Coenen <maco@android.com>
+Date: Fri, 16 Feb 2018 09:47:15 +0100
+Subject: ANDROID: binder: synchronize_rcu() when using POLLFREE.
+
+From: Martijn Coenen <maco@android.com>
+
+commit 5eeb2ca02a2f6084fc57ae5c244a38baab07033a upstream.
+
+To prevent races with ep_remove_waitqueue() removing the
+waitqueue at the same time.
+
+Reported-by: syzbot+a2a3c4909716e271487e@syzkaller.appspotmail.com
+Signed-off-by: Martijn Coenen <maco@android.com>
+Cc: stable <stable@vger.kernel.org> # 4.14+
+Signed-off-by: Mattias Nissler <mnissler@chromium.org>
+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
+@@ -2623,6 +2623,15 @@ static int binder_free_thread(struct bin
+               wake_up_poll(&thread->wait, POLLHUP | POLLFREE);
+       }
++      /*
++       * This is needed to avoid races between wake_up_poll() above and
++       * and ep_remove_waitqueue() called for other reasons (eg the epoll file
++       * descriptor being closed); ep_remove_waitqueue() holds an RCU read
++       * lock, so we can be sure it's done after calling synchronize_rcu().
++       */
++      if (thread->looper & BINDER_LOOPER_STATE_POLL)
++              synchronize_rcu();
++
+       if (send_reply)
+               binder_send_failed_reply(send_reply, BR_DEAD_REPLY);
+       binder_release_work(&thread->todo);
diff --git a/queue-4.4/series b/queue-4.4/series
new file mode 100644 (file)
index 0000000..5e35bd5
--- /dev/null
@@ -0,0 +1,2 @@
+android-binder-remove-waitqueue-when-thread-exits.patch
+android-binder-synchronize_rcu-when-using-pollfree.patch
diff --git a/queue-4.9/series b/queue-4.9/series
new file mode 100644 (file)
index 0000000..5e35bd5
--- /dev/null
@@ -0,0 +1,2 @@
+android-binder-remove-waitqueue-when-thread-exits.patch
+android-binder-synchronize_rcu-when-using-pollfree.patch