diff options
author | comex | 2015-01-29 22:03:23 -0500 |
---|---|---|
committer | comex | 2015-01-29 22:03:23 -0500 |
commit | 7e0c75a3b0a247ec7e1272773191b8bb3e652fc4 (patch) | |
tree | be7d254a745f9ce827051e2b848f49fc6f50345c | |
parent | ... (diff) | |
download | substitute-7e0c75a3b0a247ec7e1272773191b8bb3e652fc4.tar.gz |
ok, it works for now, until i have more energy to refactor it properly
-rw-r--r-- | ios-bootstrap/posixspawn-hook.c | 53 | ||||
-rw-r--r-- | ios-bootstrap/unrestrict.c | 18 |
2 files changed, 42 insertions, 29 deletions
diff --git a/ios-bootstrap/posixspawn-hook.c b/ios-bootstrap/posixspawn-hook.c index ec384c9..c2e62ef 100644 --- a/ios-bootstrap/posixspawn-hook.c +++ b/ios-bootstrap/posixspawn-hook.c @@ -36,7 +36,7 @@ static bool spawn_unrestrict(pid_t pid, bool should_resume, bool is_exec) { const char *argv[] = {prog, pid_s, should_resume_s, is_exec_s, NULL}; pid_t prog_pid; if (old_posix_spawn(&prog_pid, prog, NULL, NULL, (char **) argv, NULL)) { - ib_log("posixspawn-hook: couldn't start unrestrict-me - oh well..."); + ib_log("posixspawn-hook: couldn't start unrestrict - oh well..."); return false; } int xstat; @@ -162,24 +162,37 @@ static int hook_posix_spawn_generic(__typeof__(posix_spawn) *old, if (safe_mode) goto skip; + + /* XXX Even async on a separate thread, task_for_pid from launchd hangs in + * kernel - AMFI permitUnrestrictedDebugging waiting on some mach port. + * Normally (from other processes) task_for_pid doesn't even ask amfid + * because we have the right entitlements, but it doesn't usually *hang*. + * Probably should do what Substrate does and only launch a process for the + * few actually restricted executables. I was originally hesitant about + * this because of complications with fat files. Whatever. */ + bool need_unrestrict = getuid() == 0; + /* Deal with the dumb __restrict section. A complication is that this * could actually be an exec. */ /* TODO skip this if Substrate is doing it anyway */ - bool was_suspended = flags & POSIX_SPAWN_START_SUSPENDED; - flags |= POSIX_SPAWN_START_SUSPENDED; - if (posix_spawnattr_setflags(&my_attr, flags)) - goto crap; - if (flags & POSIX_SPAWN_SETEXEC) { - /* make the marker fd; hope you weren't using that */ - if (dup2(2, 255) != 255) { - ib_log("dup2 failure - %s", strerror(errno)); - goto skip; - } - if (fcntl(255, F_SETFD, FD_CLOEXEC)) + bool was_suspended; + if (need_unrestrict) { + was_suspended = flags & POSIX_SPAWN_START_SUSPENDED; + flags |= POSIX_SPAWN_START_SUSPENDED; + if (posix_spawnattr_setflags(&my_attr, flags)) goto crap; - ib_log("spawning unrestrict"); - if (!spawn_unrestrict(getpid(), !was_suspended, true)) - goto skip; + if (flags & POSIX_SPAWN_SETEXEC) { + /* make the marker fd; hope you weren't using that */ + if (dup2(2, 255) != 255) { + ib_log("dup2 failure - %s", strerror(errno)); + goto skip; + } + if (fcntl(255, F_SETFD, FD_CLOEXEC)) + goto crap; + ib_log("spawning unrestrict"); + if (!spawn_unrestrict(getpid(), !was_suspended, true)) + goto skip; + } } ib_log("**"); int ret = old(pidp, path, file_actions, &my_attr, argv, envp_to_use); @@ -189,13 +202,6 @@ static int hook_posix_spawn_generic(__typeof__(posix_spawn) *old, /* Since it returned, obviously it was not SETEXEC, so we need to * unrestrict it ourself. */ pid_t pid = *pidp; - /* XXX Even async on a separate thread, task_for_pid from launchd hangs in - * kernel - AMFI permitUnrestrictedDebugging waiting on some mach port. - * Normally (from other processes) task_for_pid doesn't even ask amfid - * because we have the right entitlements, but it doesn't usually *hang*. - * Probably should do what Substrate does and only launch a process for the - * few actually restricted executables. I was originally hesitant about - * this because of complications with fat files. Whatever. */ #if 0 dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); @@ -211,7 +217,8 @@ static int hook_posix_spawn_generic(__typeof__(posix_spawn) *old, free(error); }); #else - spawn_unrestrict(pid, !was_suspended, false); + if (need_unrestrict) + spawn_unrestrict(pid, !was_suspended, false); #endif goto cleanup; crap: diff --git a/ios-bootstrap/unrestrict.c b/ios-bootstrap/unrestrict.c index d966670..d8d14dd 100644 --- a/ios-bootstrap/unrestrict.c +++ b/ios-bootstrap/unrestrict.c @@ -17,6 +17,7 @@ int main(int argc, char **argv) { ib_log("unrestrict: wrong number of args"); return 1; } + const char *pids = argv[1]; char *end; long pid = strtol(pids, &end, 10); @@ -46,14 +47,16 @@ int main(int argc, char **argv) { return 0; } - ib_log("unrestrict: unrestricting %d (sr=%s, ie=%s)", (int) pid, + ib_log("unrestrict: unrestricting %ld (sr=%s, ie=%s)", pid, should_resume, is_exec); + int ec = 1; + mach_port_t task; - kern_return_t kr = task_for_pid(mach_task_self(), pid, &task); + kern_return_t kr = task_for_pid(mach_task_self(), (pid_t) pid, &task); if (kr) { ib_log("unrestrict: TFP fail: %d", kr); - return 1; + goto fail; } if (is_exec[0] == '1') { @@ -73,12 +76,12 @@ int main(int argc, char **argv) { break; } else if (ret == -1) { ib_log("proc_pidfdinfo: %s", strerror(errno)); - return 1; + goto fail; } if (retries++ == 20) { ib_log("still in parent process after 20 retries"); - return 1; + goto fail; } wait_us *= 2; if (wait_us > 200000) @@ -93,8 +96,11 @@ int main(int argc, char **argv) { if (sret) { ib_log("unrestrict: substitute_ios_unrestrict => %d (%s)", sret, err); + ec = 1; } + ec = 0; +fail: if (should_resume[0] == '1') { if ((kill(pid, SIGCONT))) { ib_log("unrestrict: kill SIGCONT: %s", strerror(errno)); @@ -102,5 +108,5 @@ int main(int argc, char **argv) { } } - return sret; + return ec; } |