From 985f0e9ca5905af7791f39fddd005f0c9f8fe081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 19 Jan 2022 12:45:37 +0100 Subject: [PATCH] macOS: Don't print stack trace via lldb on test failure if SIP prevents it If the CSR_ALLOW_UNRESTRICTED_FS bit of System Integrity Protection (SIP) is enabled lldb will fail to print a valid stack trace when launched from the crashed process, and might also resulting in hanging or crashing the parent process (Terminal e.g.): https://github.com/llvm/llvm-project/issues/53254 We detect this situation and avoid printing a stack trace if so. Pick-to: 6.3 6.2 Change-Id: Iad8cab5fcdc545d810ca4d4e985aefc0988d0234 Reviewed-by: Timur Pocheptsov --- src/corelib/kernel/qcore_mac.mm | 33 ++++++++++++++++++++++++++++++++ src/corelib/kernel/qcore_mac_p.h | 1 + src/testlib/qtestcase.cpp | 9 ++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qcore_mac.mm b/src/corelib/kernel/qcore_mac.mm index 435b2a61506..162e55fa0da 100644 --- a/src/corelib/kernel/qcore_mac.mm +++ b/src/corelib/kernel/qcore_mac.mm @@ -58,6 +58,7 @@ #include +#include "qendian.h" #include "qhash.h" #include "qpair.h" #include "qmutex.h" @@ -376,6 +377,38 @@ bool qt_mac_runningUnderRosetta() return translated; return false; } + +std::optional qt_mac_sipConfiguration() +{ + static auto configuration = []() -> std::optional { + QIOType nvram = IORegistryEntryFromPath(kIOMasterPortDefault, "IODeviceTree:/options"); + if (!nvram) { + qWarning("Failed to locate NVRAM entry in IO registry"); + return {}; + } + + QCFType csrConfig = IORegistryEntryCreateCFProperty(nvram, + CFSTR("csr-active-config"), kCFAllocatorDefault, IOOptionBits{}); + if (!csrConfig) { + qWarning("Failed to locate SIP config in NVRAM"); + return {}; + } + + if (auto type = CFGetTypeID(csrConfig); type != CFDataGetTypeID()) { + qWarning() << "Unexpected SIP config type" << CFCopyTypeIDDescription(type); + return {}; + } + + QByteArray data = QByteArray::fromRawCFData(csrConfig.as()); + if (data.size() != sizeof(uint32_t)) { + qWarning() << "Unexpected SIP config size" << data.size(); + return {}; + } + + return qFromLittleEndian(data.constData()); + }(); + return configuration; +} #endif bool qt_apple_isApplicationExtension() diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index 05bd5b7baa5..0000f3b656c 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -207,6 +207,7 @@ private: #ifdef Q_OS_MACOS Q_CORE_EXPORT bool qt_mac_applicationIsInDarkMode(); Q_CORE_EXPORT bool qt_mac_runningUnderRosetta(); +Q_CORE_EXPORT std::optional qt_mac_sipConfiguration(); #endif #ifndef QT_NO_DEBUG_STREAM diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 673605307fc..ee94cdde440 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -212,7 +212,14 @@ static void stackTrace() if (debuggerPresent() || hasSystemCrashReporter()) return; -#if defined(Q_OS_LINUX) || (defined(Q_OS_MACOS) && !defined(Q_PROCESSOR_ARM_64)) +#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS) + +#if defined(Q_OS_MACOS) + #define CSR_ALLOW_UNRESTRICTED_FS (1 << 1) + std::optional sipConfiguration = qt_mac_sipConfiguration(); + if (!sipConfiguration || !(*sipConfiguration & CSR_ALLOW_UNRESTRICTED_FS)) + return; // LLDB will fail to provide a valid stack trace +#endif const int msecsFunctionTime = qRound(QTestLog::msecsFunctionTime()); const int msecsTotalTime = qRound(QTestLog::msecsTotalTime());