Skip to content

Commit

Permalink
fix: undev gKernelVersion
Browse files Browse the repository at this point in the history
kpf: add spawn_validate_persona patch

Fix iOS 17.6 beta 1 spawn (not tested)
  • Loading branch information
asdfugil authored and khcrysalis committed Jul 4, 2024
1 parent 30964fe commit 2d26ac8
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 6 deletions.
8 changes: 5 additions & 3 deletions checkra1n/kpf/kpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,16 @@ static inline int64_t adrp_off(uint32_t adrp)
return sxt64((((((uint64_t)adrp >> 5) & 0x7ffffULL) << 2) | (((uint64_t)adrp >> 29) & 0x3ULL)) << 12, 33);
}

#ifdef DEV_BUILD

extern struct kernel_version
{
uint32_t darwinMajor;
uint32_t darwinMinor;
uint32_t darwinRevision;
const char* kernel_version_string;
uint32_t xnuMajor;
} gKernelVersion;
#endif


/********** ********** ********** ********** ********** Components ********** ********** ********** ********** **********/

Expand All @@ -119,11 +120,12 @@ extern kpf_component_t kpf_launch_constraints;
extern kpf_component_t kpf_mach_port;
extern kpf_component_t kpf_nvram;
extern kpf_component_t kpf_overlay;
extern kpf_component_t kpf_proc_selfname;
extern kpf_component_t kpf_ramdisk;
extern kpf_component_t kpf_spawn_validate_persona;
extern kpf_component_t kpf_trustcache;
extern kpf_component_t kpf_vfs;
extern kpf_component_t kpf_vm_prot;
extern kpf_component_t kpf_proc_selfname;

/********** ********** ********** ********** ********** Exports ********** ********** ********** ********** **********/

Expand Down
8 changes: 5 additions & 3 deletions checkra1n/kpf/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ uint32_t* follow_call(uint32_t *from)
return target;
}

#ifdef DEV_BUILD

struct kernel_version gKernelVersion;
static void kpf_kernel_version_init(xnu_pf_range_t *text_const_range)
{
Expand All @@ -147,6 +147,7 @@ static void kpf_kernel_version_init(xnu_pf_range_t *text_const_range)
kernelVersionString = memmem(text_const_range->cacheable_base, text_const_range->size, kernelVersionStringMarker, strlen(kernelVersionStringMarker));
if(kernelVersionString == NULL) panic("No kernel version string found");
}
gKernelVersion.kernel_version_string = kernelVersionString;
const char *start = kernelVersionString + strlen(kernelVersionStringMarker);
char *end = NULL;
errno = 0;
Expand All @@ -165,7 +166,7 @@ static void kpf_kernel_version_init(xnu_pf_range_t *text_const_range)
if(errno) panic("Error parsing kernel version");
printf("Detected Kernel version Darwin: %d.%d.%d xnu: %d\n", gKernelVersion.darwinMajor, gKernelVersion.darwinMinor, gKernelVersion.darwinRevision, gKernelVersion.xnuMajor);
}
#endif


// Imports from shellcode.S
extern uint32_t sandbox_shellcode[], sandbox_shellcode_setuid_patch[], sandbox_shellcode_ptrs[], sandbox_shellcode_end[];
Expand Down Expand Up @@ -1738,13 +1739,14 @@ kpf_component_t* const kpf_components[] = {
&kpf_launch_constraints,
&kpf_mach_port,
&kpf_nvram,
&kpf_proc_selfname,
&kpf_shellcode,
&kpf_spawn_validate_persona,
&kpf_overlay,
&kpf_ramdisk,
&kpf_trustcache,
&kpf_vfs,
&kpf_vm_prot,
&kpf_proc_selfname
};

static void kpf_cmd(const char *cmd, char *args)
Expand Down
55 changes: 55 additions & 0 deletions checkra1n/kpf/persona.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include "kpf.h"
#include <pongo.h>
#include <xnu/xnu.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

bool found_spawn_validate_persona = false;
bool spawn_validate_persona_callback(struct xnu_pf_patch *patch, uint32_t *opcode_stream) {
if (found_spawn_validate_persona)
panic_at(opcode_stream, "spawn_validate_persona: Found twice!");
puts("KPF: Found spawn_validate_persona");
found_spawn_validate_persona = true;
opcode_stream[3] = NOP;
opcode_stream[5] = NOP;
return true;
}

void kpf_spawn_validate_persona_patch(xnu_pf_patchset_t* patchset) {
if (gKernelVersion.xnuMajor < 11215 && (gKernelVersion.darwinMajor != 23 || gKernelVersion.darwinMinor < 6)) return;

// Since iOS 17.6b1, there is a check in spawn_validate_persona to forbid non-root
// callers to spawn root processes, we patch the check for uid == 0 and gid == 0
// for the processe to be spawned out
// /x 001a40b900000034000a40b900000034000e40b900000034:10feffff100000ff10feffff100000ff10feffff100000ff
uint64_t matches[] = {
0xb9401a00, // ldr w{0-15}, [x{16-31}, #0x18]
0x34000000, // cbz w{0-15}, ... <---- caller uid check
0xb9400a00, // ldr w{0-15}, [x{16-31}, #0x8]
0x34000000, // cbz w{0-15}, ... <---- wanted uid check
0xb9400e00, // ldr w{0-15}, [x{16-31}, #0xc]
0x34000000 // cbz w{0-15}, ... <---- wanted gid check
};

uint64_t masks[] = {
0xfffffe10,
0xff000010,
0xfffffe10,
0xff000010,
0xfffffe10,
0xff000010,
};

xnu_pf_maskmatch(patchset, "spawn_validate_persona", matches, masks, sizeof(matches)/sizeof(uint64_t), true, (void*)spawn_validate_persona_callback);
}

kpf_component_t kpf_spawn_validate_persona =
{
.patches =
{
{ NULL, "__TEXT_EXEC", "__text", XNU_PF_ACCESS_32BIT, kpf_spawn_validate_persona_patch },
{},
},
};

0 comments on commit 2d26ac8

Please sign in to comment.