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); _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits