Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=986 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 Proof of Concept: https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/41351.zip # Iranian Exploit DataBase = http://IeDb.Ir [2017-02-17]