From 0d519877b6fbd732e3c9ea477b996603892d1e31 Mon Sep 17 00:00:00 2001 From: opa334 Date: Sat, 10 Aug 2024 18:32:46 +0200 Subject: [PATCH] Stop redirecting all execve calls to posix_spawn, turns out some sandbox profiles block posix_spawn but allow execve... (Fixes #614) --- BaseBin/launchdhook/src/spawn_hook.c | 2 +- BaseBin/systemhook/src/common.c | 115 +++++++++++++-------------- BaseBin/systemhook/src/common.h | 11 +-- BaseBin/systemhook/src/main.c | 22 +---- 4 files changed, 61 insertions(+), 89 deletions(-) diff --git a/BaseBin/launchdhook/src/spawn_hook.c b/BaseBin/launchdhook/src/spawn_hook.c index 4db8a48cc..795c292ec 100644 --- a/BaseBin/launchdhook/src/spawn_hook.c +++ b/BaseBin/launchdhook/src/spawn_hook.c @@ -132,7 +132,7 @@ int __posix_spawn_hook(pid_t *restrict pid, const char *restrict path, } } - return spawn_hook_common(pid, path, desc, argv, envp, __posix_spawn_orig_wrapper, systemwide_trust_binary, platform_set_process_debugged, jbsetting(jetsamMultiplier)); + return posix_spawn_hook_shared(pid, path, desc, argv, envp, __posix_spawn_orig_wrapper, systemwide_trust_binary, platform_set_process_debugged, jbsetting(jetsamMultiplier)); } void initSpawnHooks(void) diff --git a/BaseBin/systemhook/src/common.c b/BaseBin/systemhook/src/common.c index 2ac21235a..b22b7c63c 100644 --- a/BaseBin/systemhook/src/common.c +++ b/BaseBin/systemhook/src/common.c @@ -97,22 +97,25 @@ int __posix_spawn_orig(pid_t *restrict pid, const char *restrict path, struct _p return syscall(SYS_posix_spawn, pid, path, desc, argv, envp); } +int __execve_orig(const char *path, char *const argv[], char *const envp[]) +{ + return syscall(SYS_execve, path, argv, envp); +} + // 1. Ensure the binary about to be spawned and all of it's dependencies are trust cached // 2. Insert "DYLD_INSERT_LIBRARIES=/usr/lib/systemhook.dylib" into all binaries spawned // 3. Increase Jetsam limit to more sane value (Multipler defined as JETSAM_MULTIPLIER) -int spawn_hook_common(pid_t *restrict pid, const char *restrict path, - struct _posix_spawn_args_desc *desc, - char *const argv[restrict], - char *const envp[restrict], - void *orig, - int (*trust_binary)(const char *path, xpc_object_t preferredArchsArray), - int (*set_process_debugged)(uint64_t pid, bool fullyDebugged), - double jetsamMultiplier) +static int spawn_exec_hook_common(const char *path, + char *const argv[restrict], + char *const envp[restrict], + struct _posix_spawn_args_desc *desc, + int (*trust_binary)(const char *path, xpc_object_t preferredArchsArray), + double jetsamMultiplier, + int (^orig)(char *const envp[restrict])) { - int (*pspawn_orig)(pid_t *restrict, const char *restrict, struct _posix_spawn_args_desc *, char *const[restrict], char *const[restrict]) = orig; if (!path) { - return pspawn_orig(pid, path, desc, argv, envp); + return orig(envp); } posix_spawnattr_t attr = NULL; @@ -230,60 +233,14 @@ int spawn_hook_common(pid_t *restrict pid, const char *restrict path, *(int*)(attrStruct + POSIX_SPAWNATTR_OFF_MEMLIMIT_INACTIVE) = memlimit_inactive * jetsamMultiplier; } } - - // On iOS 16, disable launch constraints - // Not working, doesn't seem feasable - // if (__builtin_available(iOS 16.0, *)) { - // uint32_t bufsize = PATH_MAX; - // char executablePath[PATH_MAX]; - // _NSGetExecutablePath(executablePath, &bufsize); - // // We could do the following here - // // posix_spawnattr_set_launch_type_np(*attrp, 0); - // // But I don't know how to get the compiler to weak link it - // // So we just set it by offset - // if (getpid() == 1) { - // FILE *f = fopen("/var/mobile/launch_type.txt", "a"); - // const char *toLog = path; - // if (!strcmp(path, "/usr/libexec/xpcproxy") && argv) { - // if (argv[0]) { - // if (argv[1]) { - // toLog = argv[1]; - // } - // } - // } - // fprintf(f, "%s has launch type %u\n", toLog, *(uint8_t *)(attrStruct + POSIX_SPAWNATTR_OFF_LAUNCH_TYPE)); - // fclose(f); - // } - // else if (!strcmp(executablePath, "/usr/libexec/xpcproxy")) { - // FILE *f = fopen("/tmp/launch_type_xpcproxy.txt", "a"); - // if (f) { - // fprintf(f, "%s has launch type %u\n", path, *(uint8_t *)(attrStruct + POSIX_SPAWNATTR_OFF_LAUNCH_TYPE)); - // fclose(f); - // } - // } - // else { - // os_log(OS_LOG_DEFAULT, "systemhook %{public}s has launch type %u\n", path, *(uint8_t *)(attrStruct + POSIX_SPAWNATTR_OFF_LAUNCH_TYPE)); - // } - - // *(uint8_t *)(attrStruct + POSIX_SPAWNATTR_OFF_LAUNCH_TYPE) = ... - // if (!strcmp(path, "/usr/libexec/xpcproxy") && argv) { - // if (argv[0]) { - // if (argv[1]) { - // if (string_has_prefix(argv[1], "com.apple.WebKit.WebContent.")) { - // *(uint8_t *)(attrStruct + POSIX_SPAWNATTR_OFF_LAUNCH_TYPE) = 0; - // } - // } - // } - // } - // } } } - int retval = -1; + int r = -1; if ((shouldInsertJBEnv && JBEnvAlreadyInsertedCount == 1) || (!shouldInsertJBEnv && JBEnvAlreadyInsertedCount == 0 && !hasSafeModeVariable)) { // we're already good, just call orig - retval = pspawn_orig(pid, path, desc, argv, envp); + r = orig(envp); } else { // the state we want to be in is not the state we are in right now @@ -332,11 +289,32 @@ int spawn_hook_common(pid_t *restrict pid, const char *restrict path, envbuf_unsetenv(&envc, "_MSSafeMode"); } - retval = pspawn_orig(pid, path, desc, argv, envc); + r = orig(envc); + envbuf_free(envc); } - if (retval == 0 && pid != NULL) { + return r; +} + +int posix_spawn_hook_shared(pid_t *restrict pid, + const char *restrict path, + struct _posix_spawn_args_desc *desc, + char *const argv[restrict], + char *const envp[restrict], + void *orig, + int (*trust_binary)(const char *path, xpc_object_t preferredArchsArray), + int (*set_process_debugged)(uint64_t pid, bool fullyDebugged), + double jetsamMultiplier) +{ + int (*posix_spawn_orig)(pid_t *restrict, const char *restrict, struct _posix_spawn_args_desc *, char *const[restrict], char *const[restrict]) = orig; + + int r = spawn_exec_hook_common(path, argv, envp, desc, trust_binary, jetsamMultiplier, ^int(char *const envp_patched[restrict]){ + return posix_spawn_orig(pid, path, desc, argv, envp_patched); + }); + + if (r == 0 && pid && desc) { + posix_spawnattr_t attr = desc->attrp; short flags = 0; if (posix_spawnattr_getflags(&attr, &flags) == 0) { if (flags & POSIX_SPAWN_START_SUSPENDED) { @@ -348,5 +326,20 @@ int spawn_hook_common(pid_t *restrict pid, const char *restrict path, } } - return retval; + return r; +} + +int execve_hook_shared(const char *path, + char *const argv[], + char *const envp[], + void *orig, + int (*trust_binary)(const char *path, xpc_object_t preferredArchsArray)) +{ + int (*execve_orig)(const char *, char *const[], char *const[]) = orig; + + int r = spawn_exec_hook_common(path, argv, envp, NULL, trust_binary, 0, ^int(char *const envp_patched[restrict]){ + return execve_orig(path, argv, envp_patched); + }); + + return r; } diff --git a/BaseBin/systemhook/src/common.h b/BaseBin/systemhook/src/common.h index 1f25f4ff7..a14d06be8 100644 --- a/BaseBin/systemhook/src/common.h +++ b/BaseBin/systemhook/src/common.h @@ -18,13 +18,8 @@ bool string_has_prefix(const char *str, const char* prefix); bool string_has_suffix(const char* str, const char* suffix); int __posix_spawn_orig(pid_t *restrict pid, const char *restrict path, struct _posix_spawn_args_desc *desc, char *const argv[restrict], char * const envp[restrict]); +int __execve_orig(const char *path, char *const argv[], char *const envp[]); int resolvePath(const char *file, const char *searchPath, int (^attemptHandler)(char *path)); -int spawn_hook_common(pid_t *restrict pid, const char *restrict path, - struct _posix_spawn_args_desc *desc, - char *const argv[restrict], - char *const envp[restrict], - void *orig, - int (*trust_binary)(const char *path, xpc_object_t preferredArchsArray), - int (*set_process_debugged)(uint64_t pid, bool fullyDebugged), - double jetsamMultiplier); \ No newline at end of file +int posix_spawn_hook_shared(pid_t *restrict pid, const char *restrict path, struct _posix_spawn_args_desc *desc, char *const argv[restrict], char *const envp[restrict], void *orig, int (*trust_binary)(const char *path, xpc_object_t preferredArchsArray), int (*set_process_debugged)(uint64_t pid, bool fullyDebugged), double jetsamMultiplier); +int execve_hook_shared(const char *path, char *const argv[], char *const envp[], void *orig, int (*trust_binary)(const char *path, xpc_object_t preferredArchsArray)); \ No newline at end of file diff --git a/BaseBin/systemhook/src/main.c b/BaseBin/systemhook/src/main.c index f3a22f825..00ca4a1bd 100644 --- a/BaseBin/systemhook/src/main.c +++ b/BaseBin/systemhook/src/main.c @@ -255,34 +255,18 @@ bool should_enable_tweaks(void) int __posix_spawn_hook(pid_t *restrict pid, const char *restrict path, struct _posix_spawn_args_desc *desc, char *const argv[restrict], char * const envp[restrict]) { - return spawn_hook_common(pid, path, desc, argv, envp, (void *)__posix_spawn_orig, jbclient_trust_binary, jbclient_platform_set_process_debugged, jbclient_jbsettings_get_double("jetsamMultiplier")); + return posix_spawn_hook_shared(pid, path, desc, argv, envp, (void *)__posix_spawn_orig, jbclient_trust_binary, jbclient_platform_set_process_debugged, jbclient_jbsettings_get_double("jetsamMultiplier")); } int __posix_spawn_hook_with_filter(pid_t *restrict pid, const char *restrict path, char *const argv[restrict], char * const envp[restrict], struct _posix_spawn_args_desc *desc, int *ret) { - *ret = spawn_hook_common(pid, path, desc, argv, envp, (void *)__posix_spawn_orig, jbclient_trust_binary, jbclient_platform_set_process_debugged, jbclient_jbsettings_get_double("jetsamMultiplier")); + *ret = posix_spawn_hook_shared(pid, path, desc, argv, envp, (void *)__posix_spawn_orig, jbclient_trust_binary, jbclient_platform_set_process_debugged, jbclient_jbsettings_get_double("jetsamMultiplier")); return 1; } int __execve_hook(const char *path, char *const argv[], char *const envp[]) { - // For execve, just make it call posix_spawn instead - // Since posix_spawn is hooked, all the logic will happen in there - - posix_spawnattr_t attr = NULL; - posix_spawnattr_init(&attr); - posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETEXEC); - int result = posix_spawn(NULL, path, NULL, &attr, argv, envp); - if (attr) { - posix_spawnattr_destroy(&attr); - } - - if(result != 0) { // posix_spawn will return errno and restore errno if it fails - errno = result; // so we need to set errno by ourself - return -1; - } - - return result; + return execve_hook_shared(path, argv, envp, (void *)__execve_orig, jbclient_trust_binary); } __attribute__((constructor)) static void initializer(void)