|
|
OS X IOKit kernel code execution due to incorrect bounds checking in Intel GPU driver ( x2 ) | ||||
| Project Member Reported by ianbeer@google.com, May 20 2014 | Back to list | ||||
IGAccelGLContext::getTargetAndMethodForIndex doesn't correctly bounds check the selector:
__text:000000000000873A ; IGAccelGLContext::getTargetAndMethodForIndex(IOService **, unsigned int)
__text:000000000000873A push rbp
__text:000000000000873B mov rbp, rsp
__text:000000000000873E mov [rsi], rdi
__text:0000000000008741 lea eax, [rdx-106h] ; rdx is controlled selector index
__text:0000000000008747 cmp eax, 100h
__text:000000000000874C jnb short loc_8765 ; pass selectors 0..0x105 && 0x207+ to superclass
__text:000000000000874E add edx, 0FFFFFE00h ; selectors in the range 0x106..0x206 pass the test,
; this then subtracts 0x200, underflowing for any selector
; in the range 0x106..0x1ff
__text:0000000000008754 lea rax, [rdx+rdx*2]
__text:0000000000008758 shl rax, 4
__text:000000000000875C add rax, [rdi+1098h] ; underflowed value used as index into array of IOExternalMethods
__text:0000000000008763 pop rbp
__text:0000000000008764 retn
the correct range of selectors is 0x200..0x206, however the selector is only checked to be in the range 0x106..0x206 :-)
Exploitation of this issue depends on the value stored at this+0x1098 (which should point to the static methodDescs array.) I've already reported another bug
where this field can be NULL. Combined with this new bug you get a nice way to exploit that NULL pointer deref without having to be able to map the NULL page:
Since the index will underflow a 32-bit value then be extended to 64-bits and multiplied by 48 you end up with a pointer something like this: 0x0000002fffffdf18
which is a mappable address for a 64-bit process, even one which is sandboxed and has a PAGEZERO segment since it's above 4GB. By crafting a valid IOExternalMethod
struct there you can trivially get kernel RIP control.
Once the NULL methodDescs bug is fixed, exploitability of this bug will depend on what data happens to be in the oob region and whether it could be interpreted
as a valid IOExternalMethod structure. (I haven't tried to exploit this approach yet, but the methodDescs array is near various vtables and other
IOExternalMethod arrays so I wouldn't rule it out.)
The OpenCL userclient (different code path) suffers from a similar bad bounds checking issue, I've attached a PoC for that too.
Project Member
Comment 1
by
ianbeer@google.com,
May 20 2014
,
May 23 2014
,
Jul 3 2014
,
Jul 30 2014
,
Jul 31 2014
|
|||||
| ► Sign in to add a comment | |||||