|
|
LG: Multiple race conditions in lgdrmserver binder service. | ||
| Project Member Reported by markbrand@google.com, Nov 9 2016 | Back to list | ||
The lgdrmserver binder service (/system/bin/lgdrmserver) implements a handle
system to store pointers to objects allocated by the drm implementation
(/system/lib/liblgdrm.so).
In several places, these handles are retrieved from a received binder Parcel, looked up in a SortedVector under a global lock, the lock is
then released and the handle is passed to one of the DRM_xyz functions in
liblgdrm.so which then uses the handle without holding any locks.
The attached PoC simply creates a number of process instances using the function
DRM_ProcessInit (lgdrm binder ordinal 2), then triggers the race condition by
trying to cause a double free on one of these instances using DRM_ProcessEnd
(lgdrm binder ordinal 8). The race window looks something like the following:
ILGDrmService::ProcessEnd(void* handle) {
lock(gLock); // <-- second thread takes this lock
void* process = gProcesses.find(handle); // <-- handle is still valid
unlock(gLock);
DRM_ProcessEnd(process);
lock(gLock); // <-- before first thread takes this lock
gProcesses.remove(handle);
unlock(gLock);
}
This will result in heap corruption during the second call to DRM_ProcessEnd
with the (now invalid) process object, which will eventually crash the
lgdrmserver process (usually during a subsequent call to malloc).
Several other functions in lgdrmserver follow a similar pattern, and require
additional locking to be safe.
The PoC has been tested on an LG G4 running build-id MRA58K
Build fingerprint: 'lge/p1_global_com/p1:6.0/MRA58K/1624210305d45:user/release-keys'
Revision: '11'
ABI: 'arm'
pid: 32314, tid: 32314, name: lgdrmserver >>> /system/bin/lgdrmserver <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xf6e801d8
r0 00000003 r1 f6b4012c r2 00000008 r3 00000001
r4 0000001f r5 f6b4012c r6 f6e40140 r7 f6b40134
r8 f6b40000 r9 000d0027 sl 00000005 fp 00000000
ip f700f10c sp ffd0c2c8 lr f6b4013c pc f6fd46c2 cpsr 000f0030
backtrace:
#00 pc 0004b6c2 /system/lib/libc.so (arena_dalloc_bin_locked_impl.isra.27+365)
#01 pc 0005c85f /system/lib/libc.so (je_tcache_bin_flush_small+206)
#02 pc 00055917 /system/lib/libc.so (ifree+290)
#03 pc 000587a3 /system/lib/libc.so (je_free+374)
#04 pc 000241c9 /system/lib/liblgdrm.so (DRMPart_ProcessEnd+340)
#05 pc 00018331 /system/lib/liblgdrm.so (DRM_ProcessEnd+72)
#06 pc 000056a5 /system/bin/lgdrmserver
#07 pc 00005fbd /system/bin/lgdrmserver
#08 pc 00019931 /system/lib/libbinder.so (_ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j+60)
#09 pc 0001eccb /system/lib/libbinder.so (_ZN7android14IPCThreadState14executeCommandEi+550)
#10 pc 0001ee35 /system/lib/libbinder.so (_ZN7android14IPCThreadState20getAndExecuteCommandEv+64)
#11 pc 0001ee99 /system/lib/libbinder.so (_ZN7android14IPCThreadState14joinThreadPoolEb+48)
#12 pc 00004661 /system/bin/lgdrmserver
#13 pc 000174a9 /system/lib/libc.so (__libc_init+44)
#14 pc 00004784 /system/bin/lgdrmserver
This bug is subject to a 90 day disclosure deadline. If 90 days elapse
without a broadly available patch, then the bug report will automatically
become visible to the public.
Project Member
Comment 1
by
markbrand@google.com,
Nov 14 2016
,
Jan 9 2017
,
Feb 9 2017
Derestricting since the issue is reported fixed. Haven't been able to check fix since the update is not available for my test device yet. |
|||
| ► Sign in to add a comment | |||