From: Greg Kroah-Hartman Date: Sun, 6 Oct 2019 07:32:48 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.9.196~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a43505949b61633f9d97e404719016b1e0ff5869;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: android-binder-remove-waitqueue-when-thread-exits.patch android-binder-synchronize_rcu-when-using-pollfree.patch --- diff --git a/queue-4.9/android-binder-remove-waitqueue-when-thread-exits.patch b/queue-4.9/android-binder-remove-waitqueue-when-thread-exits.patch new file mode 100644 index 00000000000..37f39f508cd --- /dev/null +++ b/queue-4.9/android-binder-remove-waitqueue-when-thread-exits.patch @@ -0,0 +1,70 @@ +From f5cb779ba16334b45ba8946d6bfa6d9834d1527f Mon Sep 17 00:00:00 2001 +From: Martijn Coenen +Date: Fri, 5 Jan 2018 11:27:07 +0100 +Subject: ANDROID: binder: remove waitqueue when thread exits. + +From: Martijn Coenen + +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 +Reported-by: syzbot +Cc: stable # 4.14 +[backport BINDER_LOOPER_STATE_POLL logic as well] +Signed-off-by: Mattias Nissler +Signed-off-by: Greg Kroah-Hartman +--- + 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 { +@@ -2628,6 +2629,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); +@@ -2651,6 +2664,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.9/android-binder-synchronize_rcu-when-using-pollfree.patch b/queue-4.9/android-binder-synchronize_rcu-when-using-pollfree.patch new file mode 100644 index 00000000000..62b91b69277 --- /dev/null +++ b/queue-4.9/android-binder-synchronize_rcu-when-using-pollfree.patch @@ -0,0 +1,39 @@ +From 5eeb2ca02a2f6084fc57ae5c244a38baab07033a Mon Sep 17 00:00:00 2001 +From: Martijn Coenen +Date: Fri, 16 Feb 2018 09:47:15 +0100 +Subject: ANDROID: binder: synchronize_rcu() when using POLLFREE. + +From: Martijn Coenen + +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 +Cc: stable # 4.14+ +Signed-off-by: Mattias Nissler +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -2641,6 +2641,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);