Skip to content

Commit 3a6430c

Browse files
Martijn Coenengregkh
authored andcommitted
ANDROID: binder: don't queue async transactions to thread.
This can cause issues with processes using the poll() interface: 1) client sends two oneway transactions 2) the second one gets queued on async_todo (because the server didn't handle the first one yet) 3) server returns from poll(), picks up the first transaction and does transaction work 4) server is done with the transaction, sends BC_FREE_BUFFER, and the second transaction gets moved to thread->todo 5) libbinder's handlePolledCommands() only handles the commands in the current data buffer, so doesn't see the new transaction 6) the server continues running and issues a new outgoing transaction. Now, it suddenly finds the incoming oneway transaction on its thread todo, and returns that to userspace. 7) userspace does not expect this to happen; it may be holding a lock while making the outgoing transaction, and if handling the incoming trasnaction requires taking the same lock, userspace will deadlock. By queueing the async transaction to the proc workqueue, we make sure it's only picked up when a thread is ready for proc work. Signed-off-by: Martijn Coenen <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent bb74562 commit 3a6430c

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

drivers/android/binder.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3351,11 +3351,13 @@ static int binder_thread_write(struct binder_proc *proc,
33513351
BUG_ON(buf_node->proc != proc);
33523352
w = binder_dequeue_work_head_ilocked(
33533353
&buf_node->async_todo);
3354-
if (!w)
3354+
if (!w) {
33553355
buf_node->has_async_transaction = 0;
3356-
else
3356+
} else {
33573357
binder_enqueue_work_ilocked(
3358-
w, &thread->todo);
3358+
w, &proc->todo);
3359+
binder_wakeup_proc_ilocked(proc);
3360+
}
33593361
binder_node_inner_unlock(buf_node);
33603362
}
33613363
trace_binder_transaction_buffer_release(buffer);

0 commit comments

Comments
 (0)