[Mac] Add a crash key containing System Integrity Protection state
There have been several confusing crashes in the last few months where knowing that SIP was a factor would have made them easier to investigate. System Integrity Policy is available via the private `csr_get_active_config` system call, with CSR standing for Configurable Security Restrictions. The raw policy value is logged along with two specific flags that are of interest. Change-Id: Ie92dad97308155a75416740edfba926b513b8a31 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6174054 Reviewed-by: Avi Drissman <avi@chromium.org> Commit-Queue: Mark Rowe <markrowe@chromium.org> Cr-Commit-Position: refs/heads/main@{#1406432}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
19e42617c3
commit
eda907474c
@ -6,7 +6,7 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "content/common/mac/task_port_policy.h"
|
||||
#include "content/common/mac/system_policy.h"
|
||||
|
||||
namespace content {
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "mojo/public/cpp/system/platform_handle.h"
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#include "content/common/mac/task_port_policy.h"
|
||||
#include "content/common/mac/system_policy.h"
|
||||
#endif
|
||||
|
||||
namespace content {
|
||||
|
@ -338,8 +338,8 @@ source_set("common") {
|
||||
sources += [
|
||||
"mac/attributed_string_type_converters.h",
|
||||
"mac/attributed_string_type_converters.mm",
|
||||
"mac/task_port_policy.cc",
|
||||
"mac/task_port_policy.h",
|
||||
"mac/system_policy.cc",
|
||||
"mac/system_policy.h",
|
||||
]
|
||||
deps += [ "//sandbox/mac:seatbelt" ]
|
||||
}
|
||||
|
113
content/common/mac/system_policy.cc
Normal file
113
content/common/mac/system_policy.cc
Normal file
@ -0,0 +1,113 @@
|
||||
// Copyright 2022 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "content/common/mac/system_policy.h"
|
||||
|
||||
#include "base/debug/crash_logging.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
|
||||
extern "C" {
|
||||
int __mac_syscall(const char* policy, int op, void* arg);
|
||||
int csr_get_active_config(uint32_t* config);
|
||||
}
|
||||
|
||||
namespace content {
|
||||
|
||||
namespace {
|
||||
|
||||
// From AppleMobileFileIntegrity.kext`policy_syscall() on macOS 12.4 21F79.
|
||||
enum AmfiStatusFlags {
|
||||
// Boot arg: `amfi_unrestrict_task_for_pid`.
|
||||
kAmfiOverrideUnrestrictedDebugging = 1 << 0,
|
||||
// Boot arg: `amfi_allow_any_signature`.
|
||||
kAmfiAllowInvalidSignatures = 1 << 1,
|
||||
// Boot arg: `amfi_get_out_of_my_way`.
|
||||
kAmfiAllowEverything = 1 << 2,
|
||||
};
|
||||
|
||||
// From
|
||||
// https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.41.3/bsd/sys/csr.h
|
||||
enum SystemSecurityPolicy : uint32_t {
|
||||
AllowUntrustedKernelExtensions = 1 << 0,
|
||||
AllowUnrestrictedFileSystem = 1 << 1,
|
||||
AllowTaskForPid = 1 << 2,
|
||||
AllowKernelDebugger = 1 << 3,
|
||||
AllowAppleInternal = 1 << 4,
|
||||
AllowUnrestrictedDTrace = 1 << 5,
|
||||
AllowUnrestrictedNVRAM = 1 << 6,
|
||||
AllowDeviceConfiguration = 1 << 7,
|
||||
AllowAnyRecoveryOS = 1 << 8,
|
||||
AllowUnapprovedKernelExtensions = 1 << 9,
|
||||
AllowExecutablePolicyOverride = 1 << 10,
|
||||
AllowUnauthenticatedRoot = 1 < 11,
|
||||
AllowResearchGuests = 1 << 12,
|
||||
};
|
||||
|
||||
base::expected<SystemSecurityPolicy, int> GetSystemSecurityPolicy() {
|
||||
uint32_t policy = 0;
|
||||
if (int error = csr_get_active_config(&policy)) {
|
||||
return base::unexpected(error);
|
||||
}
|
||||
|
||||
return base::expected<SystemSecurityPolicy, int>(
|
||||
static_cast<SystemSecurityPolicy>(policy));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool MachTaskPortPolicy::AmfiIsAllowEverything() const {
|
||||
return (amfi_status & kAmfiAllowEverything) != 0;
|
||||
}
|
||||
|
||||
base::expected<MachTaskPortPolicy, int> GetMachTaskPortPolicy() {
|
||||
MachTaskPortPolicy policy;
|
||||
|
||||
// Undocumented MACF system call to Apple Mobile File Integrity.kext. In
|
||||
// macOS 12.4 21F79 (and at least back to macOS 12.0), this returns a
|
||||
// bitmask containing the AMFI status flags.
|
||||
if (__mac_syscall("AMFI", 0x60, &policy.amfi_status) != 0) {
|
||||
return base::unexpected(errno);
|
||||
}
|
||||
|
||||
return policy;
|
||||
}
|
||||
|
||||
void SetSystemPolicyCrashKeys() {
|
||||
static auto* task_port_policy_crash_key = base::debug::AllocateCrashKeyString(
|
||||
"amfi-status", base::debug::CrashKeySize::Size64);
|
||||
static auto* system_security_policy_crash_key =
|
||||
base::debug::AllocateCrashKeyString("system-integrity-protection",
|
||||
base::debug::CrashKeySize::Size64);
|
||||
|
||||
auto task_port_policy = GetMachTaskPortPolicy();
|
||||
if (task_port_policy.has_value()) {
|
||||
base::debug::SetCrashKeyString(
|
||||
task_port_policy_crash_key,
|
||||
base::StringPrintf("rv=0 status=0x%llx allow_everything=%d",
|
||||
task_port_policy->amfi_status,
|
||||
task_port_policy->AmfiIsAllowEverything()));
|
||||
} else {
|
||||
base::debug::SetCrashKeyString(
|
||||
task_port_policy_crash_key,
|
||||
base::StringPrintf("rv=%d", task_port_policy.error()));
|
||||
}
|
||||
|
||||
auto system_security_policy = GetSystemSecurityPolicy();
|
||||
if (system_security_policy.has_value()) {
|
||||
base::debug::SetCrashKeyString(
|
||||
system_security_policy_crash_key,
|
||||
base::StringPrintf(
|
||||
"rv=0 status=0x%llx task_for_pid=%d kernel_debugger=%d",
|
||||
system_security_policy.value(),
|
||||
(system_security_policy.value() & AllowTaskForPid) != 0,
|
||||
(system_security_policy.value() & AllowKernelDebugger) != 0));
|
||||
|
||||
} else {
|
||||
base::debug::SetCrashKeyString(
|
||||
system_security_policy_crash_key,
|
||||
base::StringPrintf("rv=%d", task_port_policy.error()));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace content
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CONTENT_COMMON_MAC_TASK_PORT_POLICY_H_
|
||||
#define CONTENT_COMMON_MAC_TASK_PORT_POLICY_H_
|
||||
#ifndef CONTENT_COMMON_MAC_SYSTEM_POLICY_H_
|
||||
#define CONTENT_COMMON_MAC_SYSTEM_POLICY_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@ -31,4 +31,4 @@ void SetSystemPolicyCrashKeys();
|
||||
|
||||
} // namespace content
|
||||
|
||||
#endif // CONTENT_COMMON_MAC_TASK_PORT_POLICY_H_
|
||||
#endif // CONTENT_COMMON_MAC_SYSTEM_POLICY_H_
|
@ -1,64 +0,0 @@
|
||||
// Copyright 2022 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "content/common/mac/task_port_policy.h"
|
||||
|
||||
#include "base/debug/crash_logging.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
|
||||
extern "C" {
|
||||
int __mac_syscall(const char* policy, int op, void* arg);
|
||||
}
|
||||
|
||||
namespace content {
|
||||
|
||||
namespace {
|
||||
|
||||
// From AppleMobileFileIntegrity.kext`policy_syscall() on macOS 12.4 21F79.
|
||||
enum AmfiStatusFlags {
|
||||
// Boot arg: `amfi_unrestrict_task_for_pid`.
|
||||
kAmfiOverrideUnrestrictedDebugging = 1 << 0,
|
||||
// Boot arg: `amfi_allow_any_signature`.
|
||||
kAmfiAllowInvalidSignatures = 1 << 1,
|
||||
// Boot arg: `amfi_get_out_of_my_way`.
|
||||
kAmfiAllowEverything = 1 << 2,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
bool MachTaskPortPolicy::AmfiIsAllowEverything() const {
|
||||
return (amfi_status & kAmfiAllowEverything) != 0;
|
||||
}
|
||||
|
||||
base::expected<MachTaskPortPolicy, int> GetMachTaskPortPolicy() {
|
||||
MachTaskPortPolicy policy;
|
||||
|
||||
// Undocumented MACF system call to Apple Mobile File Integrity.kext. In
|
||||
// macOS 12.4 21F79 (and at least back to macOS 12.0), this returns a
|
||||
// bitmask containing the AMFI status flags.
|
||||
if (__mac_syscall("AMFI", 0x60, &policy.amfi_status) != 0) {
|
||||
return base::unexpected(errno);
|
||||
}
|
||||
|
||||
return policy;
|
||||
}
|
||||
|
||||
void SetSystemPolicyCrashKeys() {
|
||||
static auto* crash_key = base::debug::AllocateCrashKeyString(
|
||||
"amfi-status", base::debug::CrashKeySize::Size64);
|
||||
|
||||
auto task_port_policy = GetMachTaskPortPolicy();
|
||||
if (task_port_policy.has_value()) {
|
||||
base::debug::SetCrashKeyString(
|
||||
crash_key,
|
||||
base::StringPrintf("rv=0 status=0x%llx allow_everything=%d",
|
||||
task_port_policy->amfi_status,
|
||||
task_port_policy->AmfiIsAllowEverything()));
|
||||
} else {
|
||||
base::debug::SetCrashKeyString(
|
||||
crash_key, base::StringPrintf("rv=%d", task_port_policy.error()));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace content
|
Reference in New Issue
Block a user