1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 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
|