aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcomex2015-01-29 22:03:23 -0500
committercomex2015-01-29 22:03:23 -0500
commit7e0c75a3b0a247ec7e1272773191b8bb3e652fc4 (patch)
treebe7d254a745f9ce827051e2b848f49fc6f50345c
parent... (diff)
downloadsubstitute-7e0c75a3b0a247ec7e1272773191b8bb3e652fc4.tar.gz
ok, it works for now, until i have more energy to refactor it properly
-rw-r--r--ios-bootstrap/posixspawn-hook.c53
-rw-r--r--ios-bootstrap/unrestrict.c18
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;
}