mac: kern.nx is not present in 10.14.4 et seq, but NX is always enabled

Bug: crashpad:295
Change-Id: Id1de68d402d229b43fab5e8d15b0fe23c618ce08
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2119645
Commit-Queue: Justin Cohen <justincohen@chromium.org>
Reviewed-by: Justin Cohen <justincohen@chromium.org>
This commit is contained in:
Mark Mentovai 2020-03-25 19:31:09 -04:00 committed by Commit Bot
parent faae6470cf
commit d3859d91fd
2 changed files with 44 additions and 3 deletions

View File

@ -14,6 +14,7 @@
#include "snapshot/mac/system_snapshot_mac.h"
#include <AvailabilityMacros.h>
#include <stddef.h>
#include <sys/sysctl.h>
#include <sys/types.h>
@ -22,6 +23,7 @@
#include <algorithm>
#include "base/logging.h"
#include "base/scoped_clear_errno.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "snapshot/cpu_context.h"
@ -34,11 +36,16 @@ namespace crashpad {
namespace {
template <typename T>
int ReadIntSysctlByName_NoLog(const char* name, T* value) {
size_t value_len = sizeof(*value);
return sysctlbyname(name, value, &value_len, nullptr, 0);
}
template <typename T>
T ReadIntSysctlByName(const char* name, T default_value) {
T value;
size_t value_len = sizeof(value);
if (sysctlbyname(name, &value, &value_len, nullptr, 0) != 0) {
if (ReadIntSysctlByName_NoLog(name, &value) != 0) {
PLOG(WARNING) << "sysctlbyname " << name;
return default_value;
}
@ -338,7 +345,35 @@ std::string SystemSnapshotMac::MachineDescription() const {
bool SystemSnapshotMac::NXEnabled() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return ReadIntSysctlByName<int>("kern.nx", 0);
int value;
if (ReadIntSysctlByName_NoLog("kern.nx", &value) != 0) {
{
// Support for the kern.nx sysctlbyname is compiled out of production
// kernels on macOS 10.14.4 and later, although its available in
// development and debug kernels. Compare 10.14.3
// xnu-4903.241.1/bsd/kern/kern_sysctl.c to 10.15.0
// xnu-6153.11.26/bsd/kern/kern_sysctl.c (10.14.4 xnu source is not yet
// available). In newer production kernels, NX is always enabled. See
// 10.15.0 xnu-6153.11.26/osfmk/x86_64/pmap.c nx_enabled.
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_14
const bool nx_always_enabled = true;
#else // DT >= 10.14
base::ScopedClearErrno reset_errno;
const bool nx_always_enabled = MacOSXMinorVersion() >= 14;
#endif // DT >= 10.14
if (nx_always_enabled) {
return true;
}
}
// Even if sysctlbyname should have worked, NX is enabled by default in all
// supported configurations, so return true even while warning.
PLOG(WARNING) << "sysctlbyname kern.nx";
return true;
}
return value;
}
void SystemSnapshotMac::TimeZone(DaylightSavingTimeStatus* dst_status,

View File

@ -126,6 +126,12 @@ TEST_F(SystemSnapshotMacTest, MachineDescription) {
EXPECT_FALSE(system_snapshot().MachineDescription().empty());
}
TEST_F(SystemSnapshotMacTest, NXEnabled) {
// Assume NX will always be enabled, as it was always enabled by default on
// all supported versions of macOS.
EXPECT_TRUE(system_snapshot().NXEnabled());
}
} // namespace
} // namespace test
} // namespace crashpad