diff options
author | comex | 2015-07-11 13:18:41 -0400 |
---|---|---|
committer | comex | 2015-07-11 14:06:16 -0400 |
commit | 7de586f0dde91a3bd5433f879f8b614c2ebaf579 (patch) | |
tree | 286d5c6fa7b06c5a9623bfefb635e2befb218a42 /darwin-bootstrap | |
parent | stuff! (diff) | |
download | substitute-7de586f0dde91a3bd5433f879f8b614c2ebaf579.tar.gz |
fix?
Diffstat (limited to 'darwin-bootstrap')
-rw-r--r-- | darwin-bootstrap/bundle-loader.c | 65 | ||||
-rw-r--r-- | darwin-bootstrap/ib-log.h | 2 | ||||
-rw-r--r-- | darwin-bootstrap/substituted.m | 6 | ||||
-rw-r--r-- | darwin-bootstrap/unrestrict.c | 6 |
4 files changed, 47 insertions, 32 deletions
diff --git a/darwin-bootstrap/bundle-loader.c b/darwin-bootstrap/bundle-loader.c index ced3233..9006bf0 100644 --- a/darwin-bootstrap/bundle-loader.c +++ b/darwin-bootstrap/bundle-loader.c @@ -30,6 +30,7 @@ static struct { static pthread_mutex_t hello_reply_mtx = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t hello_reply_cond = PTHREAD_COND_INITIALIZER; static xxpc_object_t hello_reply; +static bool hello_reply_ready; #define GET(funcs, handle, name) (funcs)->name = dlsym(handle, #name) @@ -113,12 +114,7 @@ static enum bundle_test_result do_bundle_test_type( } /* return false if the info was invalid */ -static bool load_bundle_with_info(xxpc_object_t info) { - if (IB_VERBOSE) { - char *desc = xxpc_copy_description(info); - ib_log("load_bundle_with_info: %s", desc); - free(desc); - } +static bool check_bundle_with_info(xxpc_object_t info) { bool any = xxpc_dictionary_get_bool(info, "any"); enum bundle_test_result btr = do_bundle_test_type(info, "bundles", cf_has_bundle); @@ -147,38 +143,47 @@ do_load:; } static bool handle_hello_reply(xxpc_object_t dict) { + if (IB_VERBOSE) { + char *desc = xxpc_copy_description(dict); + ib_log("hello_reply: %s", desc); + free(desc); + } xxpc_object_t bundles = xxpc_dictionary_get_value(dict, "bundles"); if (!bundles || xxpc_get_type(bundles) != XXPC_TYPE_ARRAY) return false; for (size_t i = 0, count = xxpc_array_get_count(bundles); i < count; i++) { - if (!load_bundle_with_info(xxpc_array_get_value(bundles, i))) + if (!check_bundle_with_info(xxpc_array_get_value(bundles, i))) return false; } return true; } +static void signal_hello_reply(xxpc_object_t object) { + if (hello_reply_ready) + return; + pthread_mutex_lock(&hello_reply_mtx); + hello_reply = object; + hello_reply_ready = true; + pthread_cond_signal(&hello_reply_cond); + pthread_mutex_unlock(&hello_reply_mtx); +} + static void handle_xxpc_object(xxpc_object_t object, bool is_reply) { const char *msg; xxpc_type_t ty = xxpc_get_type(object); if (ty == XXPC_TYPE_DICTIONARY) { if (is_reply) { - pthread_mutex_lock(&hello_reply_mtx); - hello_reply = object; - pthread_cond_signal(&hello_reply_cond); - pthread_mutex_unlock(&hello_reply_mtx); + signal_hello_reply(xxpc_retain(object)); return; } msg = "received extraneous message from substituted"; - goto complain; } else if (ty == XXPC_TYPE_ERROR) { + signal_hello_reply(NULL); msg = "XPC error communicating with substituted"; - goto complain; } else { msg = "unknown object received from XPC"; - goto complain; } -complain:; char *desc = xxpc_copy_description(object); ib_log("%s: %s", msg, desc); free(desc); @@ -224,24 +229,30 @@ static void init() { * time changes. */ uint64_t then = mach_absolute_time() + 10 * NSEC_PER_SEC; pthread_mutex_lock(&hello_reply_mtx); - while (!hello_reply) { + while (!hello_reply_ready) { uint64_t now = mach_absolute_time(); uint64_t remaining = now >= then ? 0 : then - now; struct timespec remaining_ts = {.tv_sec = remaining / NSEC_PER_SEC, .tv_nsec = remaining % NSEC_PER_SEC}; - if (pthread_cond_timedwait_relative_np(&hello_reply_cond, &hello_reply_mtx, - &remaining_ts)) { - if (errno == ETIMEDOUT) { + int err = pthread_cond_timedwait_relative_np(&hello_reply_cond, + &hello_reply_mtx, + &remaining_ts); + if (err != 0) { + if (err == ETIMEDOUT) ib_log("ACK - didn't receive a reply from substituted in time!"); - goto bad; - } else { - ib_log("pthread_cond_timedwait failed"); - goto bad; - } + else + ib_log("pthread_cond_timedwait failed: %s", strerror(err)); + pthread_mutex_unlock(&hello_reply_mtx); + goto bad; } } pthread_mutex_unlock(&hello_reply_mtx); + if (hello_reply == NULL) { + /* thread notified us of XPC error */ + goto bad; + } + if (!handle_hello_reply(hello_reply)) { char *desc = xxpc_copy_description(hello_reply); ib_log("received invalid message from substituted: %s", desc); @@ -251,5 +262,9 @@ static void init() { return; bad: - ib_log("giving up..."); + if (hello_reply) { + xxpc_release(hello_reply); + hello_reply = NULL; + } + ib_log("giving up on loading bundles for this process..."); } diff --git a/darwin-bootstrap/ib-log.h b/darwin-bootstrap/ib-log.h index 536b1a7..c80ae63 100644 --- a/darwin-bootstrap/ib-log.h +++ b/darwin-bootstrap/ib-log.h @@ -41,4 +41,4 @@ static inline void ib_log_hex(const void *buf, size_t size) { free(hex); } -#define IB_VERBOSE 0 +#define IB_VERBOSE 1 diff --git a/darwin-bootstrap/substituted.m b/darwin-bootstrap/substituted.m index ec30a49..8e7af7c 100644 --- a/darwin-bootstrap/substituted.m +++ b/darwin-bootstrap/substituted.m @@ -2,7 +2,6 @@ #import <CoreFoundation/CoreFoundation.h> #include "xxpc.h" #include "substitute.h" -# /* This is a daemon contacted by all processes which can load extensions. It * currently does the work of reading the plists in @@ -143,8 +142,8 @@ static enum convert_filters_ret convert_filters(NSDictionary *plist_dict, for (int i = 0; i < 2; i++) { NSArray *things = [filter objectForKey:types[i].key]; + xxpc_object_t out_things = xxpc_array_create(NULL, 0); if (things) { - xxpc_object_t out_things = xxpc_array_create(NULL, 0); if (![things isKindOfClass:[NSArray class]]) return INVALID; for (NSString *name in things) { @@ -153,8 +152,8 @@ static enum convert_filters_ret convert_filters(NSDictionary *plist_dict, xxpc_array_append_value(out_things, nsstring_to_xpc(name)); } xxpc_dictionary_set_value(out_info, types[i].okey, out_things); - xxpc_release(out_things); } + xxpc_release(out_things); } return PROVISIONAL_PASS; @@ -243,6 +242,7 @@ static void init_peer(xxpc_object_t peer) { } int main() { + NSLog(@"hello from substituted"); install_deadlock_warning(); xxpc_connection_t listener = xxpc_connection_create_mach_service( "com.ex.substituted", NULL, XXPC_CONNECTION_MACH_SERVICE_LISTENER); diff --git a/darwin-bootstrap/unrestrict.c b/darwin-bootstrap/unrestrict.c index 2ea3ac6..496bf08 100644 --- a/darwin-bootstrap/unrestrict.c +++ b/darwin-bootstrap/unrestrict.c @@ -6,9 +6,9 @@ * * It exists as a separate executable because (a) such processes may be * launched with POSIX_SPAWN_SETEXEC, which makes posix_spawn act like exec and - * replace the current process, and (b) if they're not, launchd (into which - * posixspawn-hook is injected) still can't task_for_pid the child process - * itself, because it doesn't have the right entitlements. + * replace the current process, and (b) if they're not, launchd/xpcproxy (into + * which posixspawn-hook is injected) still can't task_for_pid the child + * process itself, because they don't have the right entitlements. */ #define IB_LOG_NAME "unrestrict" |