From c20239a7daea6260e395101a005417c2acc55f4e Mon Sep 17 00:00:00 2001 From: Daiki Mizukami Date: Tue, 10 Oct 2023 08:31:40 +0900 Subject: [PATCH 1/3] [common] Always spawn `login` command as the super user This allows the app to work in a jailed state (after the user has signed the app with TrollStore's method). The technique is borrowed from TrollStore's documentation: - --- App/entitlements.plist | 2 ++ Common/Controllers/SubProcess.swift | 12 +++++++++++- Common/Supporting Files/NewTermCommon.h | 7 +++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/App/entitlements.plist b/App/entitlements.plist index 6d9f8d4c..4c44529e 100644 --- a/App/entitlements.plist +++ b/App/entitlements.plist @@ -8,6 +8,8 @@ com.apple.private.security.no-container + com.apple.private.persona-mgmt + com.apple.security.iokit-user-client-class IOUserClient diff --git a/Common/Controllers/SubProcess.swift b/Common/Controllers/SubProcess.swift index 5cfdce42..a65ded2c 100644 --- a/Common/Controllers/SubProcess.swift +++ b/Common/Controllers/SubProcess.swift @@ -170,6 +170,16 @@ class SubProcess { posix_spawn_file_actions_adddup2(&actions, fds.replica, STDERR_FILENO) defer { posix_spawn_file_actions_destroy(&actions) } + var attr: posix_spawnattr_t! + posix_spawnattr_init(&attr) + defer { posix_spawnattr_destroy(&attr) } + #if !(targetEnvironment(simulator) || targetEnvironment(macCatalyst)) + // Spawn as the super user even in a jailed state, where the rootfs has the nosuid option set. + posix_spawnattr_set_persona_np(&attr, 99, POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE) + posix_spawnattr_set_persona_uid_np(&attr, 0) + posix_spawnattr_set_persona_gid_np(&attr, 0) + #endif + // TODO: At some point, come up with some way to keep track of working directory changes. // When opening a new tab, we can switch straight to the previous tab’s working directory. let argv: [UnsafeMutablePointer?] @@ -189,7 +199,7 @@ class SubProcess { } var pid = pid_t() - let result = ie_posix_spawn(&pid, Self.login, &actions, nil, argv, envp) + let result = ie_posix_spawn(&pid, Self.login, &actions, &attr, argv, envp) close(fds.replica) if result != 0 { // Fork failed. diff --git a/Common/Supporting Files/NewTermCommon.h b/Common/Supporting Files/NewTermCommon.h index 26e9a9d6..50d3ccc3 100644 --- a/Common/Supporting Files/NewTermCommon.h +++ b/Common/Supporting Files/NewTermCommon.h @@ -20,4 +20,11 @@ static inline int ie_posix_spawn(pid_t *pid, const char *path, const posix_spawn #else extern int ie_getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t buflen, struct passwd **pwretp); extern int ie_posix_spawn(pid_t *pid, const char *path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[]); + +#define POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE ((uint32_t) 1) + +// https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/libsyscall/wrappers/spawn/spawn_private.h#L87-L89 +extern int posix_spawnattr_set_persona_np(const posix_spawnattr_t *attr, uid_t persona_id, uint32_t flags); +extern int posix_spawnattr_set_persona_uid_np(const posix_spawnattr_t *attr, uid_t uid); +extern int posix_spawnattr_set_persona_gid_np(const posix_spawnattr_t *attr, gid_t gid); #endif From 333d1fc31564b750fcea37260a450554b1eedada Mon Sep 17 00:00:00 2001 From: Daiki Mizukami Date: Tue, 10 Oct 2023 18:56:53 +0900 Subject: [PATCH 2/3] [app] Add entitlements to let spawned commands access other containers --- App/entitlements.plist | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/App/entitlements.plist b/App/entitlements.plist index 4c44529e..4b616799 100644 --- a/App/entitlements.plist +++ b/App/entitlements.plist @@ -8,6 +8,10 @@ com.apple.private.security.no-container + com.apple.private.security.storage.AppDataContainers + + com.apple.private.security.storage-exempt.heritable + com.apple.private.persona-mgmt com.apple.security.iokit-user-client-class From f3852996dad1b844c227148f84c4998d5900f230 Mon Sep 17 00:00:00 2001 From: Daiki Mizukami Date: Sun, 29 Oct 2023 09:00:30 +0900 Subject: [PATCH 3/3] [common] Spawn `login` as `mobile` when `loginIsShell` is `true` --- Common/Controllers/SubProcess.swift | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Common/Controllers/SubProcess.swift b/Common/Controllers/SubProcess.swift index a65ded2c..b9a00b24 100644 --- a/Common/Controllers/SubProcess.swift +++ b/Common/Controllers/SubProcess.swift @@ -174,10 +174,13 @@ class SubProcess { posix_spawnattr_init(&attr) defer { posix_spawnattr_destroy(&attr) } #if !(targetEnvironment(simulator) || targetEnvironment(macCatalyst)) - // Spawn as the super user even in a jailed state, where the rootfs has the nosuid option set. - posix_spawnattr_set_persona_np(&attr, 99, POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE) - posix_spawnattr_set_persona_uid_np(&attr, 0) - posix_spawnattr_set_persona_gid_np(&attr, 0) + if !Self.loginIsShell { + // Spawn `login` as the super user even in a jailed state, where the rootfs has the + // nosuid option set. + posix_spawnattr_set_persona_np(&attr, 99, POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE) + posix_spawnattr_set_persona_uid_np(&attr, 0) + posix_spawnattr_set_persona_gid_np(&attr, 0) + } #endif // TODO: At some point, come up with some way to keep track of working directory changes.