New issue
Advanced search Search tips
Starred by 1 user
Status: Fixed
Owner:
Closed: Dec 2015
Cc:



Sign in to add a comment
Lack of bounds checking in IOBluetoothHCIUserClient external method dispatching allows arbitrary kernel code execution
Project Member Reported by ianbeer@google.com, Oct 12 2015 Back to list
IOBluetoothHCIUserClient uses an IOCommandGate to dispatch external methods; it passes a pointer to the structInput
of the external method as arg0 and ::SimpleDispatchWL as the Action. It neither passes nor checks the size of that structInput,
and SimpleDispatchWL goes on to read the field at +0x70 of the structInput:

__text:00000000000118EB                 mov     esi, [rbx+70h]      <-- rbx is structInput, size never checked so +0x70 can be OOB
__text:00000000000118EE                 test    esi, esi
__text:00000000000118F0                 mov     r13d, 0E00002C7h
__text:00000000000118F6                 js      loc_11C5B           <-- fail if negative
__text:00000000000118FC                 lea     rdx, _sRoutineCount
__text:0000000000011903                 cmp     esi, [rdx]
__text:0000000000011905                 jge     loc_11C5B           <-- fail if >= number of routines

This alone would be uninteresting, except that there is another fetch from rbx+0x70 which assumes the value hasn't changed:

__text:0000000000011995                 movsxd  rax, dword ptr [rbx+70h] <-- fetch OOB again
__text:0000000000011999                 mov     rcx, rax
__text:000000000001199C                 shl     rcx, 4
__text:00000000000119A0                 lea     rdx, _sRoutines
__text:00000000000119A7                 mov     r14d, [rdx+rcx+8]
__text:00000000000119AC                 cmp     r14d, 7
__text:00000000000119B0                 mov     r13d, 0E00002C2h
__text:00000000000119B6                 ja      loc_11C5B                <-- test that sRoutines[OOB].nParams is <= 7
__text:00000000000119BC                 mov     rcx, [rdx+rcx]
__text:00000000000119C0                 mov     [rbp+var_40], rcx        <-- save sRoutines[OOB].fptr into var_40

the code then sets the required registers/stack entries for the number of parameters and calls var_40:

__text:0000000000011B77                 mov     rdi, r15
__text:0000000000011B7A                 call    [rbp+var_40]

Therefore, by being able to change what follows the mach message corrisponding to this external method call in memory between the checks at +0x118eb
and the second fetch at +0x11995 we can defeat the bounds check and get a function pointer read out of bounds and called.

Tested on OS X ElCapitan 10.11 (15A284) on MacBookAir 5,2

Strongly recommended to use the gazalloc boot args as shown above to repro this!
 
bluehci_oob_demux.c
3.7 KB Download
Project Member Comment 1 by ianbeer@google.com, Oct 12 2015
Labels: Reported-2015-Oct-12 Id-629833259
Project Member Comment 2 by ianbeer@google.com, Dec 20 2015
Labels: CVE-2015-7108 Fixed-2015-Dec-08
Status: Fixed
Apple bulletin: https://support.apple.com/en-gb/HT205637
Project Member Comment 3 by ianbeer@google.com, Jan 27 2016
Labels: -Restrict-View-Commit
Sign in to add a comment