[llvm-branch-commits] [compiler-rt] 84de4fa - GetMacosAlignedVersion() fails if sysctl is not setup

Julian Lettner via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Jan 15 11:48:05 PST 2021


Author: Julian Lettner
Date: 2021-01-15T11:42:25-08:00
New Revision: 84de4faf4cae2885056c608db8256e9f039050b3

URL: https://github.com/llvm/llvm-project/commit/84de4faf4cae2885056c608db8256e9f039050b3
DIFF: https://github.com/llvm/llvm-project/commit/84de4faf4cae2885056c608db8256e9f039050b3.diff

LOG: GetMacosAlignedVersion() fails if sysctl is not setup

`GetMacosAlignedVersion()` fails for ASan-ified launchd because the
sanitizer initialization code runs before `sysctl` has been setup by
launchd.  In this situation, `sysctl kern.osproductversion` returns a
non-empty string that does not match our expectations of a
well-formatted version string.

Retrieving the kernel version (via `sysctl kern.osrelease`) still works,
so we can use it to add a fallback for this corner case.

Differential Revision: https://reviews.llvm.org/D94190

Added: 
    

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
index 6fe6991bc816..2b53d7d730d7 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
@@ -620,6 +620,23 @@ constexpr u16 GetOSMajorKernelOffset() {
 
 using VersStr = char[64];
 
+static uptr ApproximateOSVersionViaKernelVersion(VersStr vers) {
+  u16 kernel_major = GetDarwinKernelVersion().major;
+  u16 offset = GetOSMajorKernelOffset();
+  CHECK_GE(kernel_major, offset);
+  u16 os_major = kernel_major - offset;
+
+  const char *format = "%d.0";
+  if (TARGET_OS_OSX) {
+    if (os_major >= 16) {  // macOS 11+
+      os_major -= 5;
+    } else {  // macOS 10.15 and below
+      format = "10.%d";
+    }
+  }
+  return internal_snprintf(vers, sizeof(VersStr), format, os_major);
+}
+
 static void GetOSVersion(VersStr vers) {
   uptr len = sizeof(VersStr);
   if (SANITIZER_IOSSIM) {
@@ -633,17 +650,19 @@ static void GetOSVersion(VersStr vers) {
   } else {
     int res =
         internal_sysctlbyname("kern.osproductversion", vers, &len, nullptr, 0);
-    if (res) {
-      // Fallback for XNU 17 (macOS 10.13) and below that do not provide the
-      // `kern.osproductversion` property.
-      u16 kernel_major = GetDarwinKernelVersion().major;
-      u16 offset = GetOSMajorKernelOffset();
-      CHECK_LE(kernel_major, 17);
-      CHECK_GE(kernel_major, offset);
-      u16 os_major = kernel_major - offset;
-
-      auto format = TARGET_OS_OSX ? "10.%d" : "%d.0";
-      len = internal_snprintf(vers, len, format, os_major);
+
+    // XNU 17 (macOS 10.13) and below do not provide the sysctl
+    // `kern.osproductversion` entry (res != 0).
+    bool no_os_version = res != 0;
+
+    // For launchd, sanitizer initialization runs before sysctl is setup
+    // (res == 0 && len != strlen(vers), vers is not a valid version).  However,
+    // the kernel version `kern.osrelease` is available.
+    bool launchd = (res == 0 && internal_strlen(vers) < 3);
+    if (launchd) CHECK_EQ(internal_getpid(), 1);
+
+    if (no_os_version || launchd) {
+      len = ApproximateOSVersionViaKernelVersion(vers);
     }
   }
   CHECK_LT(len, sizeof(VersStr));
@@ -681,7 +700,7 @@ static void MapToMacos(u16 *major, u16 *minor) {
 }
 
 static MacosVersion GetMacosAlignedVersionInternal() {
-  VersStr vers;
+  VersStr vers = {};
   GetOSVersion(vers);
 
   u16 major, minor;
@@ -707,7 +726,7 @@ MacosVersion GetMacosAlignedVersion() {
 }
 
 DarwinKernelVersion GetDarwinKernelVersion() {
-  VersStr vers;
+  VersStr vers = {};
   uptr len = sizeof(VersStr);
   int res = internal_sysctlbyname("kern.osrelease", vers, &len, nullptr, 0);
   CHECK_EQ(res, 0);


        


More information about the llvm-branch-commits mailing list