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>
diff --git a/snapshot/mac/system_snapshot_mac.cc b/snapshot/mac/system_snapshot_mac.cc
index 21f254e..1ece816 100644
--- a/snapshot/mac/system_snapshot_mac.cc
+++ b/snapshot/mac/system_snapshot_mac.cc
@@ -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"
@@ -35,10 +37,15 @@
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 @@
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 it’s 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,
diff --git a/snapshot/mac/system_snapshot_mac_test.cc b/snapshot/mac/system_snapshot_mac_test.cc
index 69048eb..2b66592 100644
--- a/snapshot/mac/system_snapshot_mac_test.cc
+++ b/snapshot/mac/system_snapshot_mac_test.cc
@@ -126,6 +126,12 @@
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