Skip to content

Commit 0d51987

Browse files
committed
Stop redirecting all execve calls to posix_spawn, turns out some sandbox profiles block posix_spawn but allow execve... (Fixes #614)
1 parent abca19d commit 0d51987

File tree

4 files changed

+61
-89
lines changed

4 files changed

+61
-89
lines changed

BaseBin/launchdhook/src/spawn_hook.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ int __posix_spawn_hook(pid_t *restrict pid, const char *restrict path,
132132
}
133133
}
134134

135-
return spawn_hook_common(pid, path, desc, argv, envp, __posix_spawn_orig_wrapper, systemwide_trust_binary, platform_set_process_debugged, jbsetting(jetsamMultiplier));
135+
return posix_spawn_hook_shared(pid, path, desc, argv, envp, __posix_spawn_orig_wrapper, systemwide_trust_binary, platform_set_process_debugged, jbsetting(jetsamMultiplier));
136136
}
137137

138138
void initSpawnHooks(void)

BaseBin/systemhook/src/common.c

+54-61
Original file line numberDiff line numberDiff line change
@@ -97,22 +97,25 @@ int __posix_spawn_orig(pid_t *restrict pid, const char *restrict path, struct _p
9797
return syscall(SYS_posix_spawn, pid, path, desc, argv, envp);
9898
}
9999

100+
int __execve_orig(const char *path, char *const argv[], char *const envp[])
101+
{
102+
return syscall(SYS_execve, path, argv, envp);
103+
}
104+
100105
// 1. Ensure the binary about to be spawned and all of it's dependencies are trust cached
101106
// 2. Insert "DYLD_INSERT_LIBRARIES=/usr/lib/systemhook.dylib" into all binaries spawned
102107
// 3. Increase Jetsam limit to more sane value (Multipler defined as JETSAM_MULTIPLIER)
103108

104-
int spawn_hook_common(pid_t *restrict pid, const char *restrict path,
105-
struct _posix_spawn_args_desc *desc,
106-
char *const argv[restrict],
107-
char *const envp[restrict],
108-
void *orig,
109-
int (*trust_binary)(const char *path, xpc_object_t preferredArchsArray),
110-
int (*set_process_debugged)(uint64_t pid, bool fullyDebugged),
111-
double jetsamMultiplier)
109+
static int spawn_exec_hook_common(const char *path,
110+
char *const argv[restrict],
111+
char *const envp[restrict],
112+
struct _posix_spawn_args_desc *desc,
113+
int (*trust_binary)(const char *path, xpc_object_t preferredArchsArray),
114+
double jetsamMultiplier,
115+
int (^orig)(char *const envp[restrict]))
112116
{
113-
int (*pspawn_orig)(pid_t *restrict, const char *restrict, struct _posix_spawn_args_desc *, char *const[restrict], char *const[restrict]) = orig;
114117
if (!path) {
115-
return pspawn_orig(pid, path, desc, argv, envp);
118+
return orig(envp);
116119
}
117120

118121
posix_spawnattr_t attr = NULL;
@@ -230,60 +233,14 @@ int spawn_hook_common(pid_t *restrict pid, const char *restrict path,
230233
*(int*)(attrStruct + POSIX_SPAWNATTR_OFF_MEMLIMIT_INACTIVE) = memlimit_inactive * jetsamMultiplier;
231234
}
232235
}
233-
234-
// On iOS 16, disable launch constraints
235-
// Not working, doesn't seem feasable
236-
// if (__builtin_available(iOS 16.0, *)) {
237-
// uint32_t bufsize = PATH_MAX;
238-
// char executablePath[PATH_MAX];
239-
// _NSGetExecutablePath(executablePath, &bufsize);
240-
// // We could do the following here
241-
// // posix_spawnattr_set_launch_type_np(*attrp, 0);
242-
// // But I don't know how to get the compiler to weak link it
243-
// // So we just set it by offset
244-
// if (getpid() == 1) {
245-
// FILE *f = fopen("/var/mobile/launch_type.txt", "a");
246-
// const char *toLog = path;
247-
// if (!strcmp(path, "/usr/libexec/xpcproxy") && argv) {
248-
// if (argv[0]) {
249-
// if (argv[1]) {
250-
// toLog = argv[1];
251-
// }
252-
// }
253-
// }
254-
// fprintf(f, "%s has launch type %u\n", toLog, *(uint8_t *)(attrStruct + POSIX_SPAWNATTR_OFF_LAUNCH_TYPE));
255-
// fclose(f);
256-
// }
257-
// else if (!strcmp(executablePath, "/usr/libexec/xpcproxy")) {
258-
// FILE *f = fopen("/tmp/launch_type_xpcproxy.txt", "a");
259-
// if (f) {
260-
// fprintf(f, "%s has launch type %u\n", path, *(uint8_t *)(attrStruct + POSIX_SPAWNATTR_OFF_LAUNCH_TYPE));
261-
// fclose(f);
262-
// }
263-
// }
264-
// else {
265-
// os_log(OS_LOG_DEFAULT, "systemhook %{public}s has launch type %u\n", path, *(uint8_t *)(attrStruct + POSIX_SPAWNATTR_OFF_LAUNCH_TYPE));
266-
// }
267-
268-
// *(uint8_t *)(attrStruct + POSIX_SPAWNATTR_OFF_LAUNCH_TYPE) = ...
269-
// if (!strcmp(path, "/usr/libexec/xpcproxy") && argv) {
270-
// if (argv[0]) {
271-
// if (argv[1]) {
272-
// if (string_has_prefix(argv[1], "com.apple.WebKit.WebContent.")) {
273-
// *(uint8_t *)(attrStruct + POSIX_SPAWNATTR_OFF_LAUNCH_TYPE) = 0;
274-
// }
275-
// }
276-
// }
277-
// }
278-
// }
279236
}
280237
}
281238

282-
int retval = -1;
239+
int r = -1;
283240

284241
if ((shouldInsertJBEnv && JBEnvAlreadyInsertedCount == 1) || (!shouldInsertJBEnv && JBEnvAlreadyInsertedCount == 0 && !hasSafeModeVariable)) {
285242
// we're already good, just call orig
286-
retval = pspawn_orig(pid, path, desc, argv, envp);
243+
r = orig(envp);
287244
}
288245
else {
289246
// 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,
332289
envbuf_unsetenv(&envc, "_MSSafeMode");
333290
}
334291

335-
retval = pspawn_orig(pid, path, desc, argv, envc);
292+
r = orig(envc);
293+
336294
envbuf_free(envc);
337295
}
338296

339-
if (retval == 0 && pid != NULL) {
297+
return r;
298+
}
299+
300+
int posix_spawn_hook_shared(pid_t *restrict pid,
301+
const char *restrict path,
302+
struct _posix_spawn_args_desc *desc,
303+
char *const argv[restrict],
304+
char *const envp[restrict],
305+
void *orig,
306+
int (*trust_binary)(const char *path, xpc_object_t preferredArchsArray),
307+
int (*set_process_debugged)(uint64_t pid, bool fullyDebugged),
308+
double jetsamMultiplier)
309+
{
310+
int (*posix_spawn_orig)(pid_t *restrict, const char *restrict, struct _posix_spawn_args_desc *, char *const[restrict], char *const[restrict]) = orig;
311+
312+
int r = spawn_exec_hook_common(path, argv, envp, desc, trust_binary, jetsamMultiplier, ^int(char *const envp_patched[restrict]){
313+
return posix_spawn_orig(pid, path, desc, argv, envp_patched);
314+
});
315+
316+
if (r == 0 && pid && desc) {
317+
posix_spawnattr_t attr = desc->attrp;
340318
short flags = 0;
341319
if (posix_spawnattr_getflags(&attr, &flags) == 0) {
342320
if (flags & POSIX_SPAWN_START_SUSPENDED) {
@@ -348,5 +326,20 @@ int spawn_hook_common(pid_t *restrict pid, const char *restrict path,
348326
}
349327
}
350328

351-
return retval;
329+
return r;
330+
}
331+
332+
int execve_hook_shared(const char *path,
333+
char *const argv[],
334+
char *const envp[],
335+
void *orig,
336+
int (*trust_binary)(const char *path, xpc_object_t preferredArchsArray))
337+
{
338+
int (*execve_orig)(const char *, char *const[], char *const[]) = orig;
339+
340+
int r = spawn_exec_hook_common(path, argv, envp, NULL, trust_binary, 0, ^int(char *const envp_patched[restrict]){
341+
return execve_orig(path, argv, envp_patched);
342+
});
343+
344+
return r;
352345
}

BaseBin/systemhook/src/common.h

+3-8
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,8 @@ bool string_has_prefix(const char *str, const char* prefix);
1818
bool string_has_suffix(const char* str, const char* suffix);
1919

2020
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]);
21+
int __execve_orig(const char *path, char *const argv[], char *const envp[]);
2122

2223
int resolvePath(const char *file, const char *searchPath, int (^attemptHandler)(char *path));
23-
int spawn_hook_common(pid_t *restrict pid, const char *restrict path,
24-
struct _posix_spawn_args_desc *desc,
25-
char *const argv[restrict],
26-
char *const envp[restrict],
27-
void *orig,
28-
int (*trust_binary)(const char *path, xpc_object_t preferredArchsArray),
29-
int (*set_process_debugged)(uint64_t pid, bool fullyDebugged),
30-
double jetsamMultiplier);
24+
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);
25+
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));

BaseBin/systemhook/src/main.c

+3-19
Original file line numberDiff line numberDiff line change
@@ -255,34 +255,18 @@ bool should_enable_tweaks(void)
255255

256256
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])
257257
{
258-
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"));
258+
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"));
259259
}
260260

261261
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)
262262
{
263-
*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"));
263+
*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"));
264264
return 1;
265265
}
266266

267267
int __execve_hook(const char *path, char *const argv[], char *const envp[])
268268
{
269-
// For execve, just make it call posix_spawn instead
270-
// Since posix_spawn is hooked, all the logic will happen in there
271-
272-
posix_spawnattr_t attr = NULL;
273-
posix_spawnattr_init(&attr);
274-
posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETEXEC);
275-
int result = posix_spawn(NULL, path, NULL, &attr, argv, envp);
276-
if (attr) {
277-
posix_spawnattr_destroy(&attr);
278-
}
279-
280-
if(result != 0) { // posix_spawn will return errno and restore errno if it fails
281-
errno = result; // so we need to set errno by ourself
282-
return -1;
283-
}
284-
285-
return result;
269+
return execve_hook_shared(path, argv, envp, (void *)__execve_orig, jbclient_trust_binary);
286270
}
287271

288272
__attribute__((constructor)) static void initializer(void)

0 commit comments

Comments
 (0)