codenote / google-security-research

Automatically exported from code.google.com/p/google-security-research
0 stars 0 forks source link

OS X IOKit kernel code execution due to incorrect bounds checking in Intel GPU driver ( x2 ) #22

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
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.

Original issue reported on code.google.com by ianb...@google.com on 20 May 2014 at 4:23

Attachments:

GoogleCodeExporter commented 9 years ago

Original comment by ianb...@google.com on 20 May 2014 at 5:49

GoogleCodeExporter commented 9 years ago

Original comment by ianb...@google.com on 23 May 2014 at 4:37

GoogleCodeExporter commented 9 years ago
Apple advisory: http://support.apple.com/kb/HT6296

Original comment by ianb...@google.com on 3 Jul 2014 at 1:21

GoogleCodeExporter commented 9 years ago

Original comment by ianb...@google.com on 30 Jul 2014 at 5:39

GoogleCodeExporter commented 9 years ago

Original comment by cev...@google.com on 31 Jul 2014 at 12:17