Skip to content

Commit 6d2d4eb

Browse files
authored
Merge pull request #77162 from al45tair/eng/PR-137551812
[Backtracing] Bail out earlier for privileged binaries on macOS.
2 parents 9a845a0 + 2cc93cf commit 6d2d4eb

File tree

4 files changed

+54
-25
lines changed

4 files changed

+54
-25
lines changed

stdlib/public/Backtracing/modules/OS/Darwin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ extern void _dyld_process_info_for_each_segment(dyld_process_info info, uint64_t
135135
// .. Code Signing SPI .........................................................
136136

137137
#define CS_OPS_STATUS 0
138+
#define CS_GET_TASK_ALLOW 0x00000004
139+
#define CS_RUNTIME 0x00010000
138140
#define CS_PLATFORM_BINARY 0x04000000
139141
#define CS_PLATFORM_PATH 0x08000000
140142
extern int csops(int, unsigned int, void *, size_t);

stdlib/public/libexec/swift-backtrace/TargetMacOS.swift

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,21 +129,28 @@ class Target {
129129
}
130130
}
131131

132-
static func isPlatformBinary(pid: pid_t) -> Bool {
132+
static func isPrivileged(pid: pid_t) -> Bool {
133133
var flags = UInt32(0)
134134

135-
return csops(pid,
136-
UInt32(CS_OPS_STATUS),
137-
&flags,
138-
MemoryLayout<UInt32>.size) != 0 ||
139-
(flags & UInt32(CS_PLATFORM_BINARY | CS_PLATFORM_PATH)) != 0
135+
guard csops(pid,
136+
UInt32(CS_OPS_STATUS),
137+
&flags,
138+
MemoryLayout<UInt32>.size) == 0 else {
139+
return true
140+
}
141+
142+
if (flags & UInt32(CS_PLATFORM_BINARY | CS_PLATFORM_PATH | CS_RUNTIME)) != 0 {
143+
return true
144+
}
145+
146+
return (flags & UInt32(CS_GET_TASK_ALLOW)) == 0
140147
}
141148

142149
init(crashInfoAddr: UInt64, limit: Int?, top: Int, cache: Bool,
143150
symbolicate: SwiftBacktrace.Symbolication) {
144151
pid = getppid()
145152

146-
if Self.isPlatformBinary(pid: pid) {
153+
if Self.isPrivileged(pid: pid) {
147154
/* Exit silently in this case; either
148155

149156
1. We can't call csops(), because we're sandboxed, or

stdlib/public/libexec/swift-backtrace/main.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,15 @@ Generate a backtrace for the parent process.
456456
}
457457
}
458458

459+
static func unblockSignals() {
460+
var mask = sigset_t()
461+
462+
sigfillset(&mask)
463+
sigprocmask(SIG_UNBLOCK, &mask, nil)
464+
}
465+
459466
static func main() {
467+
unblockSignals()
460468
parseArguments()
461469

462470
guard let crashInfoAddr = args.crashInfo else {

stdlib/public/runtime/Backtrace.cpp

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@
4343
#endif
4444

4545
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
46+
#if __has_include(<sys/codesign.h>)
47+
#include <sys/codesign.h>
48+
#else
49+
// SPI
50+
#define CS_OPS_STATUS 0
51+
#define CS_GET_TASK_ALLOW 0x00000004
52+
#define CS_RUNTIME 0x00010000
53+
#define CS_PLATFORM_BINARY 0x04000000
54+
#define CS_PLATFORM_PATH 0x08000000
55+
extern "C" int csops(int, unsigned int, void *, size_t);
56+
#endif
4657
#include <spawn.h>
4758
#endif
4859
#include <unistd.h>
@@ -145,11 +156,6 @@ BacktraceInitializer backtraceInitializer;
145156

146157
SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_END
147158

148-
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
149-
posix_spawnattr_t backtraceSpawnAttrs;
150-
posix_spawn_file_actions_t backtraceFileActions;
151-
#endif
152-
153159
#if SWIFT_BACKTRACE_ON_CRASH_SUPPORTED
154160

155161
// We need swiftBacktracePath to be aligned on a page boundary, and it also
@@ -254,7 +260,24 @@ const char *presetToString(Preset preset) {
254260
bool isPrivileged() {
255261
return getauxval(AT_SECURE);
256262
}
257-
#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
263+
#elif defined(__APPLE__)
264+
bool isPrivileged() {
265+
if (issetugid())
266+
return true;
267+
268+
uint32_t flags = 0;
269+
if (csops(getpid(),
270+
CS_OPS_STATUS,
271+
&flags,
272+
sizeof(flags)) != 0)
273+
return true;
274+
275+
if (flags & (CS_PLATFORM_BINARY | CS_PLATFORM_PATH | CS_RUNTIME))
276+
return true;
277+
278+
return !(flags & CS_GET_TASK_ALLOW);
279+
}
280+
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
258281
bool isPrivileged() {
259282
return issetugid();
260283
}
@@ -451,17 +474,6 @@ BacktraceInitializer::BacktraceInitializer() {
451474
}
452475

453476
if (_swift_backtraceSettings.enabled == OnOffTty::On) {
454-
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
455-
// Make sure that all fds are closed except for stdin/stdout/stderr.
456-
posix_spawnattr_init(&backtraceSpawnAttrs);
457-
posix_spawnattr_setflags(&backtraceSpawnAttrs, POSIX_SPAWN_CLOEXEC_DEFAULT);
458-
459-
posix_spawn_file_actions_init(&backtraceFileActions);
460-
posix_spawn_file_actions_addinherit_np(&backtraceFileActions, STDIN_FILENO);
461-
posix_spawn_file_actions_addinherit_np(&backtraceFileActions, STDOUT_FILENO);
462-
posix_spawn_file_actions_addinherit_np(&backtraceFileActions, STDERR_FILENO);
463-
#endif
464-
465477
ErrorCode err = _swift_installCrashHandler();
466478
if (err != 0) {
467479
swift::warning(0,
@@ -993,7 +1005,7 @@ _swift_spawnBacktracer(const ArgChar * const *argv)
9931005
const_cast<char * const *>(env));
9941006
#else
9951007
int ret = posix_spawn(&child, swiftBacktracePath,
996-
&backtraceFileActions, &backtraceSpawnAttrs,
1008+
nullptr, nullptr,
9971009
const_cast<char * const *>(argv),
9981010
const_cast<char * const *>(env));
9991011
#endif

0 commit comments

Comments
 (0)