Skip to content

Commit 9939b29

Browse files
committed
binder: use wake_up_pollfree()
jira VULN-63551 cve-pre CVE-2021-47505 commit-author Eric Biggers <[email protected]> commit a880b28 wake_up_poll() uses nr_exclusive=1, so it's not guaranteed to wake up all exclusive waiters. Yet, POLLFREE *must* wake up all waiters. epoll and aio poll are fortunately not affected by this, but it's very fragile. Thus, the new function wake_up_pollfree() has been introduced. Convert binder to use wake_up_pollfree(). Reported-by: Linus Torvalds <[email protected]> Fixes: f5cb779 ("ANDROID: binder: remove waitqueue when thread exits.") Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Eric Biggers <[email protected]> (cherry picked from commit a880b28) Signed-off-by: Brett Mastbergen <[email protected]>
1 parent d581781 commit 9939b29

File tree

1 file changed

+9
-12
lines changed

1 file changed

+9
-12
lines changed

drivers/android/binder.c

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4420,23 +4420,20 @@ static int binder_thread_release(struct binder_proc *proc,
44204420
__release(&t->lock);
44214421

44224422
/*
4423-
* If this thread used poll, make sure we remove the waitqueue
4424-
* from any epoll data structures holding it with POLLFREE.
4425-
* waitqueue_active() is safe to use here because we're holding
4426-
* the inner lock.
4423+
* If this thread used poll, make sure we remove the waitqueue from any
4424+
* poll data structures holding it.
44274425
*/
4428-
if ((thread->looper & BINDER_LOOPER_STATE_POLL) &&
4429-
waitqueue_active(&thread->wait)) {
4430-
wake_up_poll(&thread->wait, EPOLLHUP | POLLFREE);
4431-
}
4426+
if (thread->looper & BINDER_LOOPER_STATE_POLL)
4427+
wake_up_pollfree(&thread->wait);
44324428

44334429
binder_inner_proc_unlock(thread->proc);
44344430

44354431
/*
4436-
* This is needed to avoid races between wake_up_poll() above and
4437-
* and ep_remove_waitqueue() called for other reasons (eg the epoll file
4438-
* descriptor being closed); ep_remove_waitqueue() holds an RCU read
4439-
* lock, so we can be sure it's done after calling synchronize_rcu().
4432+
* This is needed to avoid races between wake_up_pollfree() above and
4433+
* someone else removing the last entry from the queue for other reasons
4434+
* (e.g. ep_remove_wait_queue() being called due to an epoll file
4435+
* descriptor being closed). Such other users hold an RCU read lock, so
4436+
* we can be sure they're done after we call synchronize_rcu().
44404437
*/
44414438
if (thread->looper & BINDER_LOOPER_STATE_POLL)
44424439
synchronize_rcu();

0 commit comments

Comments
 (0)