diff options
author | comex | 2015-07-12 17:49:43 -0400 |
---|---|---|
committer | comex | 2015-07-12 17:49:43 -0400 |
commit | fc1752a7c3e90ec7d604e9a148482c106672c27b (patch) | |
tree | 2ef55bf39cc01ef7893fb650189fbdb4a0de0026 /darwin-bootstrap | |
parent | redo crash reporting - untested (but it compiles) (diff) | |
download | substitute-fc1752a7c3e90ec7d604e9a148482c106672c27b.tar.gz |
fixes
Diffstat (limited to 'darwin-bootstrap')
-rw-r--r-- | darwin-bootstrap/posixspawn-hook.c | 59 | ||||
-rw-r--r-- | darwin-bootstrap/substituted.m | 44 |
2 files changed, 68 insertions, 35 deletions
diff --git a/darwin-bootstrap/posixspawn-hook.c b/darwin-bootstrap/posixspawn-hook.c index b2a7336..50c4ca9 100644 --- a/darwin-bootstrap/posixspawn-hook.c +++ b/darwin-bootstrap/posixspawn-hook.c @@ -57,9 +57,9 @@ static int (*old_xpc_pipe_try_receive)(mach_port_t, xxpc_object_t *, mach_port_t *, void *, size_t, int); static bool g_is_launchd; -static xxpc_object_t g_argv0_to_fate; -static HTAB_STORAGE(pid_str) g_pid_to_argv0 = - HTAB_STORAGE_INIT_STATIC(&g_pid_to_argv0, pid_str); +static xxpc_object_t g_bundleid_to_fate; +static HTAB_STORAGE(pid_str) g_pid_to_bundleid = + HTAB_STORAGE_INIT_STATIC(&g_pid_to_bundleid, pid_str); static pthread_mutex_t g_dicts_lock = PTHREAD_MUTEX_INITIALIZER; static bool advance(char **strp, const char *template) { @@ -207,13 +207,15 @@ static int hook_posix_spawn_generic(__typeof__(posix_spawn) *old, static const char psh_dylib[] = "/Library/Substitute/Helpers/posixspawn-hook.dylib"; - const char *argv0 = argv[0] ?: ""; + const char *bundleid = NULL; /* which dylib should we add, if any? */ const char *dylib_to_add; if (g_is_launchd) { if (strcmp(path, "/usr/libexec/xpcproxy")) goto skip; + if (argv[0] && argv[1]) + bundleid = argv[1]; dylib_to_add = psh_dylib; } else { /* - substituted obviously doesn't want to have bundle_loader run in it @@ -242,7 +244,7 @@ static int hook_posix_spawn_generic(__typeof__(posix_spawn) *old, */ if (!strcmp(path, "/Library/Substitute/Helpers/substituted") || !strcmp(path, "/usr/sbin/notifyd") || - !strcmp(xbasename(argv0), "sshd")) + !strcmp(xbasename(argv[0] ?: ""), "sshd")) goto skip; dylib_to_add = bl_dylib; } @@ -379,9 +381,11 @@ static int hook_posix_spawn_generic(__typeof__(posix_spawn) *old, if (need_unrestrict) spawn_unrestrict(pid, !was_suspended, false); - pthread_mutex_lock(&g_dicts_lock); - *htab_setp_pid_str(&g_pid_to_argv0.h, &pid, NULL) = strdup(argv0); - pthread_mutex_unlock(&g_dicts_lock); + if (bundleid) { + pthread_mutex_lock(&g_dicts_lock); + *htab_setp_pid_str(&g_pid_to_bundleid.h, &pid, NULL) = strdup(bundleid); + pthread_mutex_unlock(&g_dicts_lock); + } goto cleanup; crap: @@ -416,17 +420,18 @@ static void after_wait_generic(pid_t pid, int stat) { return; pthread_mutex_lock(&g_dicts_lock); struct htab_bucket_pid_str *bucket = - htab_getbucket_pid_str(&g_pid_to_argv0.h, &pid); + htab_getbucket_pid_str(&g_pid_to_bundleid.h, &pid); if (!bucket) { /* probably spawned some other way / not a task */ if (IB_VERBOSE) ib_log("reaped unknown pid %d", pid); - return; + goto end; } - char *argv0 = bucket->value; - xxpc_dictionary_set_int64(g_argv0_to_fate, argv0, stat); - free(argv0); - htab_removeat_pid_str(&g_pid_to_argv0.h, bucket); + char *bundleid = bucket->value; + xxpc_dictionary_set_int64(g_bundleid_to_fate, bundleid, stat); + free(bundleid); + htab_removeat_pid_str(&g_pid_to_bundleid.h, bucket); +end: pthread_mutex_unlock(&g_dicts_lock); } @@ -473,16 +478,28 @@ int hook_xpc_pipe_try_receive(mach_port_t port_set, xxpc_object_t *requestp, return res; } xxpc_object_t reply = NULL; - if (!strcmp(name, "argv0-to-fate")) { - const char *argv0 = xxpc_dictionary_get_string(in, "argv0"); - if (!argv0) { + if (!strcmp(name, "bundleid-to-fate")) { + const char *bundleid = xxpc_dictionary_get_string(in, "bundleid"); + if (!bundleid) { ib_log("invalid hook-operation message"); return res; } reply = xxpc_dictionary_create_reply(request); - xxpc_object_t fate = xxpc_dictionary_get_value(g_argv0_to_fate, argv0); - if (fate) - xxpc_dictionary_set_value(reply, "out", fate); + xxpc_object_t out = xxpc_dictionary_create(NULL, NULL, 0); + xxpc_object_t fate = xxpc_dictionary_get_value(g_bundleid_to_fate, bundleid); + if (fate) { + if (IB_VERBOSE) { + char *desc = xxpc_copy_description(fate); + ib_log("your (%s) fate is %s", bundleid, desc); + free(desc); + } + xxpc_dictionary_set_value(out, "fate", fate); + } else { + if (IB_VERBOSE) + ib_log("your (%s) fate is unavailable", bundleid); + } + xxpc_dictionary_set_value(reply, "out", out); + xxpc_release(out); } else { ib_log("unknown hook-operation '%s'", name); return res; @@ -556,7 +573,7 @@ static void init() { * (it also decreases the amount of library code necessary to load from * disk...) */ - g_argv0_to_fate = xxpc_dictionary_create(NULL, NULL, 0); + g_bundleid_to_fate = xxpc_dictionary_create(NULL, NULL, 0); const char *image0 = _dyld_get_image_name(0); g_is_launchd = !!strstr(image0, "launchd"); diff --git a/darwin-bootstrap/substituted.m b/darwin-bootstrap/substituted.m index f03670c..2b25c17 100644 --- a/darwin-bootstrap/substituted.m +++ b/darwin-bootstrap/substituted.m @@ -200,40 +200,55 @@ enum convert_filters_ret { return PROVISIONAL_PASS; } -- (void)updateSpringBoardNeedsSafe:(const char *)argv0 then:(void (^)())then { +- (void)updateSpringBoardNeedsSafeThen:(void (^)())then { xxpc_object_t inn = xxpc_dictionary_create(NULL, NULL, 0); - xxpc_dictionary_set_string(inn, "com.ex.substiute.hook-operation", - "argv0-to-fate"); - xxpc_dictionary_set_string(inn, "argv0", argv0); + xxpc_dictionary_set_string(inn, "com.ex.substitute.hook-operation", + "bundleid-to-fate"); + xxpc_dictionary_set_string(inn, "bundleid", "com.apple.SpringBoard"); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + int to_set = REALLY_SAFE; xxpc_object_t out = NULL; vproc_swap_complex(NULL, 99999, inn, &out); - int to_set = REALLY_SAFE; if (!out) { NSLog(@"couldn't talk to launchd :( - assume worst case scenario"); goto out; } - if (xxpc_get_type(out) != XXPC_TYPE_INT64) { - NSLog(@"wrong type from launchd!?"); - goto out; + __unsafe_unretained xxpc_type_t type = xxpc_get_type(out); + if (xxpc_get_type(out) != XXPC_TYPE_DICTIONARY) + goto bad_data; + + bool crashed; + __unsafe_unretained xxpc_object_t fate = + xxpc_dictionary_get_value(out, "fate"); + if (!fate) { + /* no record yet */ + crashed = false; + } else if (xxpc_get_type(out) == XXPC_TYPE_INT64) { + int stat = (int) xxpc_int64_get_value(out); + crashed = WIFSIGNALED(stat) && WTERMSIG(stat) != SIGTERM; + } else { + goto bad_data; } - int stat = (int) xxpc_int64_get_value(out); - bool crashed = WIFSIGNALED(stat) && WTERMSIG(stat) != SIGTERM; + if (crashed) { if (g_springboard_needs_safe) { - NSLog(@"SpringBoard hung up more than once without without saying bye; using Really Safe Mode (no UI) next time :("); + NSLog(@"SpringBoard crashed while in safe mode; using Really Safe Mode (no UI) next time :("); to_set = REALLY_SAFE; } else { - NSLog(@"SpringBoard hung up without saying bye; using safe mode next time."); + NSLog(@"SpringBoard crashed; using safe mode next time."); to_set = NEEDS_SAFE; } } else { to_set = NO_SAFE; } + goto out; + bad_data: + NSLog(@"bad data %@ from launchd!?", out); + goto out; out: dispatch_async(dispatch_get_main_queue(), ^{ g_springboard_needs_safe = to_set; @@ -258,8 +273,9 @@ enum convert_filters_ret { _is_springboard = [_argv0 isEqualToString:sb_exe]; if (_is_springboard) - [self updateSpringBoardNeedsSafe:argv0 - then:^{[self handleMessageHelloRest:request];}]; + [self updateSpringBoardNeedsSafeThen:^{ + [self handleMessageHelloRest:request]; + }]; else [self handleMessageHelloRest:request]; return; |