| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/android/binder.c | 12 ++++++++++++ |
| 1 file changed, 12 insertions(+) |
| |
| --- a/drivers/android/binder.c |
| +++ b/drivers/android/binder.c |
| @@ -4302,6 +4302,18 @@ static int binder_thread_release(struct |
| if (t) |
| spin_lock(&t->lock); |
| } |
| + |
| + /* |
| + * 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); |
| + } |
| + |
| binder_inner_proc_unlock(thread->proc); |
| |
| if (send_reply) |