diff --git a/App/entitlements.plist b/App/entitlements.plist index 6d9f8d4c..4b616799 100644 --- a/App/entitlements.plist +++ b/App/entitlements.plist @@ -8,6 +8,12 @@ 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 IOUserClient diff --git a/Common/Controllers/SubProcess.swift b/Common/Controllers/SubProcess.swift index 5cfdce42..b9a00b24 100644 --- a/Common/Controllers/SubProcess.swift +++ b/Common/Controllers/SubProcess.swift @@ -170,6 +170,19 @@ 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)) + 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. // When opening a new tab, we can switch straight to the previous tab’s working directory. let argv: [UnsafeMutablePointer?] @@ -189,7 +202,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