diff options
Diffstat (limited to 'lib/darwin')
-rw-r--r-- | lib/darwin/interpose.c | 1 | ||||
-rw-r--r-- | lib/darwin/unrestrict.c | 34 |
2 files changed, 22 insertions, 13 deletions
diff --git a/lib/darwin/interpose.c b/lib/darwin/interpose.c index bf9ceb4..419fc65 100644 --- a/lib/darwin/interpose.c +++ b/lib/darwin/interpose.c @@ -123,6 +123,7 @@ static int try_bind_section(void *bind, size_t size, const struct interpose_stat } if (h->old_ptr) *(uintptr_t *) h->old_ptr = old - addend; + offset += stride; } break; } diff --git a/lib/darwin/unrestrict.c b/lib/darwin/unrestrict.c index dd852bc..70b089a 100644 --- a/lib/darwin/unrestrict.c +++ b/lib/darwin/unrestrict.c @@ -7,6 +7,10 @@ #include <errno.h> #include <mach/vm_region.h> +#define PROC_PIDFDVNODEINFO 1 +#define PROC_PIDFDVNODEINFO_SIZE 176 +int proc_pidfdinfo(int, int, int, void *, int); + static int unrestrict_macho_header(void *header, size_t size, bool *did_modify_p, char **error) { *did_modify_p = false; @@ -43,7 +47,7 @@ static int unrestrict_macho_header(void *header, size_t size, bool *did_modify_p for (uint32_t i = 0; i < sc->nsects; i++, sect++) { if (!strncmp(sect->sectname, "__restrict", 16)) { strcpy(sect->sectname, "\xf0\x9f\x92\xa9"); - *did_modify_p =true; + *did_modify_p = true; } } } @@ -72,23 +76,25 @@ int substitute_ios_unrestrict(pid_t pid, bool should_resume, char **error) { int retries = 0; int wait_us = 1; -setback: while (1) { - /* if calling from unrestrict-me, the process might not have transitioned - * yet. if it has, then TASK_DYLD_INFO will be filled with 0. */ - task_basic_info_data_t tbi; - mach_msg_type_number_t cnt = TASK_BASIC_INFO_COUNT; - - kern_return_t kr = task_info(task, TASK_BASIC_INFO, (void *) &tbi, &cnt); - if (kr || cnt != TASK_BASIC_INFO_COUNT) { - asprintf(error, "task_info: %x", kr); + /* If calling from unrestrict-me, the process might not have + * transitioned yet. We set up a dummy fd 255 in the parent process + * which was marked CLOEXEC, so test if that still exists. + * AFAICT, Substrate's equivalent to this is not actually correct. + * TODO cleanup + */ + char buf[PROC_PIDFDVNODEINFO_SIZE]; + int ret = proc_pidfdinfo(pid, 255, PROC_PIDFDVNODEINFO, buf, sizeof(buf)); + if (ret == -1 && errno == EBADF) { + break; + } else if (ret == -1) { + asprintf(error, "proc_pidfdinfo: %s", strerror(errno)); ret = SUBSTITUTE_ERR_MISC; goto fail; } - if (tbi.user_time.seconds == 0 && tbi.user_time.microseconds == 0) - break; + if (retries++ == 20) { - asprintf(error, "user_time was not 0 after 20 retries"); + asprintf(error, "still in parent process after 20 retries"); ret = SUBSTITUTE_ERR_MISC; goto fail; } @@ -101,6 +107,7 @@ setback: /* alrighty then, let's look at the damage. find the first readable * segment */ +setback:; mach_vm_address_t segm_addr = 0; mach_vm_size_t segm_size = 0; vm_region_basic_info_data_64_t info; @@ -111,6 +118,7 @@ setback: (vm_region_info_t) &info, &info_count, &object_name); if (kr == KERN_INVALID_ADDRESS) { /* nothing! maybe it's not there *yet*? this actually is possible */ + usleep(10); goto setback; } else if (kr) { asprintf(error, "mach_vm_region(%lx): %x", (long) segm_addr, kr); |