Skip to content
Commit 15b49e10 authored by Jintao Zhu's avatar Jintao Zhu
Browse files

binder: race condition by parcel finalize



Root cause:
1) a client thread calls "transact", and then, reads a java binder object from the java parcel object
2) the java binder object sends BC_ACQUIRE/BC_INCREFS, but still in the queue, not yet flushed to driver
3) the java parcel object is garbage-collect-ed, and, its finalize method may possibly sends BC_FREE_BUFFER

  Because "BC_FREE_BUFFER" is from the java finalize thread, which is different from the "client thread", so, it is possible that "BC_FREE_BUFFER" will be flushed to driver before "BC_ACQUIRE/BC_INCREFS", which makes driver destroy the related "binder_ref" object prematurely.

Consequences of the issue:
  The user space process might always hold the above java binder object, whose "handle value" is indeed invalid because the related "binder_ref" in driver is destroyed. This causes a lot of chaos inside the process:
<a> any binder call on the java binder object will be a failure, with kernel log complain: ...got transaction to invalid handle...
<b> afterward, any new bind object passed to this process will NOT create a brand new one for it, instead, it will be simply and incorrectly mapped to the above old biner object, because the new incoming one will use the same "handle value" as the old one. This will make a mess and many weird bugs.
 First, it may break "binder object identity" compare based functionality. For example, after registering a listener to a service, all following registering may fail because the latter new listener object is mapped to the old one incorrectly. The service will reject them as "already registered".
 Second, binder call on the old binder object is actually dispatched to the new remote binder object, it might even be a success if they are of the same class/interface, which is actually not we expected; and on the other hand, the new binder object may even be of different class/interface, and of course, the binder call may be a failure due to "interface descriptor check".
<c> the user space process cannot recover from the bug automatically unless restart.

Solution:
  Hold a temporary reference to the parcel object until "BC_ACQUIRE/BC_INCREFS" flushed to driver.

Bug: 139327211
Test: monkey test for one day and one night

Co-authored-by: default avatarSteven Moreland <smoreland@google.com>

Signed-off-by: default avatarJintao Zhu <zhujtcsieee@gmail.com>
Change-Id: I9345f443996b0bdef9d57ddaad119b86205e817f
parent 338f4e1d
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment