Skip to content

Commit

Permalink
refactor: use posix_spawn instead of NSTask so we can disclaim the sp…
Browse files Browse the repository at this point in the history
…awned ShipIt executable (#33468) (#34058)
  • Loading branch information
MarshallOfSound committed May 3, 2022
1 parent 7e35b91 commit 577b2ba
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 0 deletions.
1 change: 1 addition & 0 deletions patches/squirrel.mac/.patches
Expand Up @@ -2,3 +2,4 @@ build_add_gn_config.patch
fix_ensure_that_self_is_retained_until_the_racsignal_is_complete.patch
fix_use_kseccschecknestedcode_kseccsstrictvalidate_in_the_sec.patch
feat_add_new_squirrel_mac_bundle_installation_method_behind_flag.patch
refactor_use_posix_spawn_instead_of_nstask_so_we_can_disclaim_the.patch
@@ -0,0 +1,101 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <samuel.r.attard@gmail.com>
Date: Mon, 28 Mar 2022 02:36:39 -0700
Subject: refactor: use posix_spawn instead of NSTask so we can disclaim the
spawned ShipIt executable

This ensures that if the ShipIt executable is hotswapped it doesn't inherit TCC permissions

diff --git a/Squirrel/ShipIt-main.m b/Squirrel/ShipIt-main.m
index db246534e176f9c3ea2dd8b1c8659378fdc2435d..2c515ffdd67052a08ee8155c0e46b57e9721a0e5 100644
--- a/Squirrel/ShipIt-main.m
+++ b/Squirrel/ShipIt-main.m
@@ -13,6 +13,9 @@
#import <ReactiveObjC/RACSignal+Operations.h>
#import <ReactiveObjC/RACScheduler.h>

+#include <spawn.h>
+#include <sys/wait.h>
+
#import "NSError+SQRLVerbosityExtensions.h"
#import "RACSignal+SQRLTransactionExtensions.h"
#import "SQRLInstaller.h"
@@ -20,6 +23,20 @@
#import "SQRLTerminationListener.h"
#import "SQRLShipItRequest.h"

+extern char **environ;
+
+int responsibility_spawnattrs_setdisclaim(posix_spawnattr_t attrs, int disclaim)
+__attribute__((availability(macos,introduced=10.14),weak_import));
+
+#define CHECK_ERR(expr) \
+ { \
+ int err = (expr); \
+ if (err) { \
+ fprintf(stderr, "%s: %s", #expr, strerror(err)); \
+ exit(err); \
+ } \
+ }
+
// The maximum number of times ShipIt should run the same installation state, in
// an attempt to update.
//
@@ -136,11 +153,37 @@ static void installRequest(RACSignal *readRequestSignal, NSString *applicationId
NSString *exe = NSProcessInfo.processInfo.arguments[0];
NSLog(@"Launching new ShipIt at %@ with instructions to launch %@", exe, bundleURL);

- NSTask *task = [[NSTask alloc] init];
- [task setLaunchPath: exe];
- [task setArguments: @[launchSignal, bundleURL.path]];
- [task launch];
- [task waitUntilExit];
+ posix_spawnattr_t attr;
+ CHECK_ERR(posix_spawnattr_init(&attr));
+
+ if (@available(macOS 10.14, *)) {
+ // Disclaim TCC responsibilities
+ if (responsibility_spawnattrs_setdisclaim)
+ CHECK_ERR(responsibility_spawnattrs_setdisclaim(&attr, 1));
+ }
+
+ pid_t pid = 0;
+
+ const char* launchPath = [exe fileSystemRepresentation];
+ const char* signal = [launchSignal fileSystemRepresentation];
+ const char* path = [bundleURL.path fileSystemRepresentation];
+ const char* args[] = { launchPath, signal, path, 0 };
+ int status = posix_spawn(&pid, [exe UTF8String], NULL, &attr, (char *const*)args, environ);
+ if (status == 0) {
+ NSLog(@"New ShipIt pid: %i", pid);
+ do {
+ if (waitpid(pid, &status, 0) != -1) {
+ NSLog(@"ShipIt status %d", WEXITSTATUS(status));
+ } else {
+ perror("waitpid");
+ exit(1);
+ }
+ } while (!WIFEXITED(status) && !WIFSIGNALED(status));
+ } else {
+ NSLog(@"posix_spawn: %s", strerror(status));
+ }
+
+ posix_spawnattr_destroy(&attr);

NSLog(@"New ShipIt exited");
} else {
@@ -172,7 +215,13 @@ int main(int argc, const char * argv[]) {
});

if (argc < 3) {
- NSLog(@"Missing launchd job label or state path for ShipIt");
+ NSLog(@"Missing launchd job label or state path for ShipIt (%d)", argc);
+ if (argc >= 1) {
+ NSLog(@"Arg 1: {%s}", argv[0]);
+ }
+ if (argc >= 2) {
+ NSLog(@"Arg 2: {%s}", argv[1]);
+ }
return EXIT_FAILURE;
}

0 comments on commit 577b2ba

Please sign in to comment.