CVE-2 0 1 5-6 9 7 4 vulnerability analysis-vulnerability warning-the black bar safety net

ID MYHACK58:62201570200
Type myhack58
Reporter 武汉大学信息安全协会 (hell0 Dawn)
Modified 2015-12-20T00:00:00


0x00: iOS9. 1 released, Pangu previously made a topic about the They escape using the loopholes and the use of means. Then follow up to do a little analysis.

0x01: The problem is in the Apple IOHIDFamily this driving the code inside,this drive Apple is open source. In iOS, this driver provides three user-oriented state of the client: * IOHIDResourceDeviceUserClient * IOHIDLibUserClient * IOHIDEventServiceUserClient each client will provide some user-facing state of the interface functions. Apple has a lot of CVE and all this driving about. As if to say more nonsense,look at vulnerability: `int exynos_mem_mmap(struct file filp, struct vm_area_struct vma) { struct exynos_mem mem = (struct exynos_mem )filp->private_data; bool cacheable = mem->cacheable; dma_addr_t start = 0; u32 pfn = 0; u32 size = vma->vm_end - vma->vm_start;

if (vma->vm_pgoff) {//vm_pgoff is that we pass the offset start = vma->vm_pgoff << PAGE_SHIFT; pfn = vma->vm_pgoff; } else { start = mem->phybase << PAGE_SHIFT; pfn = mem->phybase; }

if (! cacheable) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

vma->vm_flags |= VM_RESERVED; vma->vm_ops = &exynos_mem_ops;

if ((vma->vm_flags & VM_WRITE) && ! (vma->vm_flags & VM_SHARED)) { pr_err("writable mapping must be shared\n"); return-EINVAL; }

if (remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot)) {//here the real establishment of the physical address and virtual address of the mapping table pr_err("mmap fail\n"); return-EINVAL; }


return 0; }`

In IOHIDResourceUserClient No. 1 Function:

IOReturn IOHIDResourceDeviceUserClient::terminateDevice() { if (_device) { _device-&gt;terminate(); } OSSafeRelease(_device); return kIOReturnSuccess; } _device is to create a virtual IOHIDDevice device pointer, is IOHIDResourceDeviceUserClient a member variable:

`class IOHIDResourceDeviceUserClient : public IOUserClient { OSDeclareDefaultStructors(IOHIDResourceDeviceUserClient);


IOHIDResource * _owner; OSDictionary * _properties; IOHIDUserDevice * _device;`

By IOHIDResourceDeviceUserClient the No. 0 function IOHIDResourceUserClient::creatDevice()created. This function of the incoming parameter to do some checks and then call the createAndStartDevice()_device allocated space:

IOReturn IOHIDResourceDeviceUserClient::createAndStartDevice() { ... _device = IOHIDUserDevice::withProperties(_properties); ... }

OK,then see terminateDevice()in the phrase:


Have to say there is a problem. OSSafeRelease the source code is like this: the

define OSSafeRelease(inst) do { if (inst) (inst)->release(); } while (0)

the release after that, and not the object the pointer is set to NULL. So,\_device be released after\_device also retains the original object pointer, pointing to a free fall of a heap block. Then go to the call IOHIDResourceDeviceUserClient the third number of the function: handleReport (a). Inside will call _device members of the method:

`IOReturn IOHIDResourceDeviceUserClient::handleReport(IOExternalMethodArguments * arguments) { ...

ret = _device->handleReportWithTimeAsync(timestamp, report, kIOHIDReportTypeInput, 0, 0, &tap);//here call a _device of the members of the method.


if (ret != kIOReturnSuccess) { IOFree(pb, sizeof(*pb)); release(); } }

return ret; }`

It's proper to USE-AFTER-FREE.

0x03 Then there is the trigger idea: 1, call IOHIDResourceDeviceUserClient::createDevice()to create a device, give _device assignment. 2, Call IOHIDResourceDeviceUserClient::teminateDevice()release _device 3, Call IOHIDResourceDeviceUserClient::handleReport()to trigger the vulnerability. Or is again calling IOHIDResourceDeviceUserClient::teminateDevice()to cause a double-free.