diff --git a/stdlib/public/Backtracing/modules/OS/Darwin.h b/stdlib/public/Backtracing/modules/OS/Darwin.h index 7d6a4183930da..e58f14c3cf9d2 100644 --- a/stdlib/public/Backtracing/modules/OS/Darwin.h +++ b/stdlib/public/Backtracing/modules/OS/Darwin.h @@ -135,6 +135,8 @@ extern void _dyld_process_info_for_each_segment(dyld_process_info info, uint64_t // .. Code Signing SPI ......................................................... #define CS_OPS_STATUS 0 +#define CS_GET_TASK_ALLOW 0x00000004 +#define CS_RUNTIME 0x00010000 #define CS_PLATFORM_BINARY 0x04000000 #define CS_PLATFORM_PATH 0x08000000 extern int csops(int, unsigned int, void *, size_t); diff --git a/stdlib/public/libexec/swift-backtrace/TargetMacOS.swift b/stdlib/public/libexec/swift-backtrace/TargetMacOS.swift index 6512aa3d7a322..098b69356cc7d 100644 --- a/stdlib/public/libexec/swift-backtrace/TargetMacOS.swift +++ b/stdlib/public/libexec/swift-backtrace/TargetMacOS.swift @@ -129,21 +129,28 @@ class Target { } } - static func isPlatformBinary(pid: pid_t) -> Bool { + static func isPrivileged(pid: pid_t) -> Bool { var flags = UInt32(0) - return csops(pid, - UInt32(CS_OPS_STATUS), - &flags, - MemoryLayout.size) != 0 || - (flags & UInt32(CS_PLATFORM_BINARY | CS_PLATFORM_PATH)) != 0 + guard csops(pid, + UInt32(CS_OPS_STATUS), + &flags, + MemoryLayout.size) == 0 else { + return true + } + + if (flags & UInt32(CS_PLATFORM_BINARY | CS_PLATFORM_PATH | CS_RUNTIME)) != 0 { + return true + } + + return (flags & UInt32(CS_GET_TASK_ALLOW)) == 0 } init(crashInfoAddr: UInt64, limit: Int?, top: Int, cache: Bool, symbolicate: SwiftBacktrace.Symbolication) { pid = getppid() - if Self.isPlatformBinary(pid: pid) { + if Self.isPrivileged(pid: pid) { /* Exit silently in this case; either 1. We can't call csops(), because we're sandboxed, or diff --git a/stdlib/public/libexec/swift-backtrace/main.swift b/stdlib/public/libexec/swift-backtrace/main.swift index f83e584639c99..5c5db1800604b 100644 --- a/stdlib/public/libexec/swift-backtrace/main.swift +++ b/stdlib/public/libexec/swift-backtrace/main.swift @@ -456,7 +456,15 @@ Generate a backtrace for the parent process. } } + static func unblockSignals() { + var mask = sigset_t() + + sigfillset(&mask) + sigprocmask(SIG_UNBLOCK, &mask, nil) + } + static func main() { + unblockSignals() parseArguments() guard let crashInfoAddr = args.crashInfo else { diff --git a/stdlib/public/runtime/Backtrace.cpp b/stdlib/public/runtime/Backtrace.cpp index b05e3883cb82c..a9a6244019e48 100644 --- a/stdlib/public/runtime/Backtrace.cpp +++ b/stdlib/public/runtime/Backtrace.cpp @@ -43,6 +43,17 @@ #endif #if TARGET_OS_OSX || TARGET_OS_MACCATALYST +#if __has_include() +#include +#else +// SPI +#define CS_OPS_STATUS 0 +#define CS_GET_TASK_ALLOW 0x00000004 +#define CS_RUNTIME 0x00010000 +#define CS_PLATFORM_BINARY 0x04000000 +#define CS_PLATFORM_PATH 0x08000000 +extern "C" int csops(int, unsigned int, void *, size_t); +#endif #include #endif #include @@ -145,11 +156,6 @@ BacktraceInitializer backtraceInitializer; SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_END -#if TARGET_OS_OSX || TARGET_OS_MACCATALYST -posix_spawnattr_t backtraceSpawnAttrs; -posix_spawn_file_actions_t backtraceFileActions; -#endif - #if SWIFT_BACKTRACE_ON_CRASH_SUPPORTED // We need swiftBacktracePath to be aligned on a page boundary, and it also @@ -254,6 +260,23 @@ const char *presetToString(Preset preset) { bool isPrivileged() { return getauxval(AT_SECURE); } +#elif TARGET_OS_OSX || TARGET_OS_MACCATALYST +bool isPrivileged() { + if (issetugid()) + return true; + + uint32_t flags = 0; + if (csops(getpid(), + CS_OPS_STATUS, + &flags, + sizeof(flags)) != 0) + return true; + + if (flags & (CS_PLATFORM_BINARY | CS_PLATFORM_PATH | CS_RUNTIME)) + return true; + + return !(flags & CS_GET_TASK_ALLOW); +} #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) bool isPrivileged() { return issetugid(); @@ -451,17 +474,6 @@ BacktraceInitializer::BacktraceInitializer() { } if (_swift_backtraceSettings.enabled == OnOffTty::On) { -#if TARGET_OS_OSX || TARGET_OS_MACCATALYST - // Make sure that all fds are closed except for stdin/stdout/stderr. - posix_spawnattr_init(&backtraceSpawnAttrs); - posix_spawnattr_setflags(&backtraceSpawnAttrs, POSIX_SPAWN_CLOEXEC_DEFAULT); - - posix_spawn_file_actions_init(&backtraceFileActions); - posix_spawn_file_actions_addinherit_np(&backtraceFileActions, STDIN_FILENO); - posix_spawn_file_actions_addinherit_np(&backtraceFileActions, STDOUT_FILENO); - posix_spawn_file_actions_addinherit_np(&backtraceFileActions, STDERR_FILENO); -#endif - ErrorCode err = _swift_installCrashHandler(); if (err != 0) { swift::warning(0, @@ -993,7 +1005,7 @@ _swift_spawnBacktracer(const ArgChar * const *argv) const_cast(env)); #else int ret = posix_spawn(&child, swiftBacktracePath, - &backtraceFileActions, &backtraceSpawnAttrs, + nullptr, nullptr, const_cast(argv), const_cast(env)); #endif