aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--darwin-bootstrap/bundle-loader.c65
-rw-r--r--darwin-bootstrap/ib-log.h2
-rw-r--r--darwin-bootstrap/substituted.m6
-rw-r--r--darwin-bootstrap/unrestrict.c6
-rwxr-xr-xscript/gen-deb.sh1
5 files changed, 48 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"
diff --git a/script/gen-deb.sh b/script/gen-deb.sh
index 5c13ac1..f39dbd3 100755
--- a/script/gen-deb.sh
+++ b/script/gen-deb.sh
@@ -24,4 +24,5 @@ cp -a darwin-bootstrap/DEBIAN $debroot/
sed "s#{VERSION}#$version#g" darwin-bootstrap/DEBIAN/control > $debroot/DEBIAN/control
#... add bootstrap stuff
# yay, old forks and deprecated compression
+rm -f out/*.deb
fakeroot dpkg-deb -Zlzma -b $debroot out/com.ex.substitute-$version.deb