aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcomex2015-07-12 17:49:43 -0400
committercomex2015-07-12 17:49:43 -0400
commitfc1752a7c3e90ec7d604e9a148482c106672c27b (patch)
tree2ef55bf39cc01ef7893fb650189fbdb4a0de0026
parentredo crash reporting - untested (but it compiles) (diff)
downloadsubstitute-fc1752a7c3e90ec7d604e9a148482c106672c27b.tar.gz
fixes
-rwxr-xr-xconfigure6
-rw-r--r--darwin-bootstrap/posixspawn-hook.c59
-rw-r--r--darwin-bootstrap/substituted.m44
-rw-r--r--lib/darwin/xxpc.h4
-rwxr-xr-xscript/gen-deb.sh2
-rw-r--r--test/test-htab.c6
6 files changed, 82 insertions, 39 deletions
diff --git a/configure b/configure
index 5026f50..8c0fbf7 100755
--- a/configure
+++ b/configure
@@ -56,8 +56,12 @@ if settings.enable_werror:
for mach in machs + [settings.host_machine()]:
settings[mach.name].cflags = ['-Werror'] + settings[mach.name].cflags
+# XXX this is a mess and wrong
+flags = ['-O3']
+if settings.host_machine().is_cross():
+ flags.append('-miphoneos-version-min=8.0')
for i in ('cflags', 'ldflags'):
- settings.host[i] = ['-miphoneos-version-min=8.0', '-O3'] + settings.host[i]
+ settings.host[i] = flags + settings.host[i]
# todo make overridable?
cc_argv = c.cc.argv()
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;
diff --git a/lib/darwin/xxpc.h b/lib/darwin/xxpc.h
index 4b5e175..7df28f6 100644
--- a/lib/darwin/xxpc.h
+++ b/lib/darwin/xxpc.h
@@ -20,6 +20,7 @@ typedef void (^xxpc_handler_t)(xxpc_object_t);
static const xxpc_object_t name = DC_CAST &x_##name
DEFINE_CONST(XXPC_TYPE_CONNECTION, _xpc_type_connection);
+DEFINE_CONST(XXPC_TYPE_BOOL, _xpc_type_error);
DEFINE_CONST(XXPC_TYPE_ERROR, _xpc_type_error);
DEFINE_CONST(XXPC_TYPE_DICTIONARY, _xpc_type_dictionary);
DEFINE_CONST(XXPC_TYPE_ARRAY, _xpc_type_array);
@@ -43,6 +44,9 @@ xxpc_object_t WRAP(xpc_retain, (xxpc_object_t));
#endif
char *WRAP(xpc_copy_description, (xxpc_object_t));
+#if OS_OBJECT_USE_OBJC
+__attribute__((ns_returns_autoreleased))
+#endif
xxpc_type_t WRAP(xpc_get_type, (xxpc_object_t));
xxpc_object_t WRAP(xpc_string_create, (const char *));
const char *WRAP(xpc_string_get_string_ptr, (xxpc_object_t));
diff --git a/script/gen-deb.sh b/script/gen-deb.sh
index 999765c..5a0d599 100755
--- a/script/gen-deb.sh
+++ b/script/gen-deb.sh
@@ -14,7 +14,7 @@ mkdir -p $debroot/usr/include/substitute
cp lib/substitute.h $debroot/usr/include/substitute/
cp substrate/substrate.h $debroot/usr/include/substitute/
mkdir -p $debroot/Library/Substitute/DynamicLibraries
-cp darwin-bootstrap/safemode-ui-hook.plist out/safemode-ui-hook.dylib $debroot/Library/Substitute/DynamicLibraries/
+#cp darwin-bootstrap/safemode-ui-hook.plist out/safemode-ui-hook.dylib $debroot/Library/Substitute/DynamicLibraries/
mkdir -p $debroot/Library/Substitute/Helpers
cp out/{posixspawn-hook.dylib,bundle-loader.dylib,unrestrict,inject-into-launchd,substituted} $debroot/Library/Substitute/Helpers/
mkdir -p $debroot/etc/rc.d
diff --git a/test/test-htab.c b/test/test-htab.c
index 9be59a3..c85d620 100644
--- a/test/test-htab.c
+++ b/test/test-htab.c
@@ -30,8 +30,8 @@ int main() {
struct htab_teststr_int *hp;
- HTAB_STORAGE(teststr_int) stor;
- HTAB_STORAGE_INIT(&stor, teststr_int);
+ HTAB_STORAGE(teststr_int) stor = HTAB_STORAGE_INIT_STATIC(&stor, teststr_int);
+ /*HTAB_STORAGE_INIT(&stor, teststr_int);*/
hp = &stor.h;
for(int i = 0; i < 100; i++) {
const char *k;
@@ -39,6 +39,8 @@ int main() {
bool new;
*htab_setp_teststr_int(hp, &k, &new) = i;
assert(new);
+ assert(htab_getbucket_teststr_int(hp, &k)->value == i);
+ assert(*htab_getp_teststr_int(hp, &k) == i);
}
{
const char *k = "foo31";