summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2023-03-28 14:48:06 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2023-03-31 23:01:51 +0200
commite81aa64280e9835121769085023034e919274745 (patch)
treeae10b9317f51cc76f2f6c700cbb39721eb195968
parent3236b64db8bb26a6c1c2c288cb47ecc08a7d526f (diff)
macOS: Move application sandbox checking to secondary thread
We use the macOS Security framework to check whether the application is sandboxed or not, in which case we might have to limit or change some of the functionality of Qt, such as which shared memory backend to use. Calls to SecStaticCodeCheckValidityWithErrors should ideally not be done on the main thread, as the function may not return immediately, and we get runtime analysis warnings about this in Xcode: This method should not be called on the main thread as it may lead to UI unresponsiveness. To improve the situation we spin up a short lived thread at library load that resolves the sandboxing state, ready to be queried when needed from Qt. Pick-to: 6.5 Change-Id: I52cdc1bf6aef05c3b93b43f67b3fb46035996b3a Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
-rw-r--r--src/corelib/kernel/qcore_mac.mm74
-rw-r--r--src/corelib/kernel/qcore_mac_p.h5
2 files changed, 57 insertions, 22 deletions
diff --git a/src/corelib/kernel/qcore_mac.mm b/src/corelib/kernel/qcore_mac.mm
index 17cd03d975..989e7d03a6 100644
--- a/src/corelib/kernel/qcore_mac.mm
+++ b/src/corelib/kernel/qcore_mac.mm
@@ -30,6 +30,10 @@
#include "qvarlengtharray.h"
#include "private/qlocking_p.h"
+#if !defined(QT_BOOTSTRAPPED)
+#include <thread>
+#endif
+
#if !defined(QT_APPLE_NO_PRIVATE_APIS)
extern "C" {
typedef uint32_t csr_config_t;
@@ -456,34 +460,62 @@ AppleApplication *qt_apple_sharedApplication()
}
#endif
+#if !defined(QT_BOOTSTRAPPED)
+
+#if defined(Q_OS_MACOS)
+namespace {
+struct SandboxChecker
+{
+ SandboxChecker() : m_thread([this]{
+ m_isSandboxed = []{
+ QCFType<SecStaticCodeRef> staticCode = nullptr;
+ NSURL *executableUrl = NSBundle.mainBundle.executableURL;
+ if (SecStaticCodeCreateWithPath((__bridge CFURLRef)executableUrl,
+ kSecCSDefaultFlags, &staticCode) != errSecSuccess)
+ return false;
+
+ QCFType<SecRequirementRef> sandboxRequirement;
+ if (SecRequirementCreateWithString(CFSTR("entitlement[\"com.apple.security.app-sandbox\"] exists"),
+ kSecCSDefaultFlags, &sandboxRequirement) != errSecSuccess)
+ return false;
+
+ if (SecStaticCodeCheckValidityWithErrors(staticCode,
+ kSecCSBasicValidateOnly, sandboxRequirement, nullptr) != errSecSuccess)
+ return false;
+
+ return true;
+ }();
+ })
+ {}
+ ~SandboxChecker() {
+ std::scoped_lock lock(m_mutex);
+ if (m_thread.joinable())
+ m_thread.detach();
+ }
+ bool isSandboxed() const {
+ std::scoped_lock lock(m_mutex);
+ if (m_thread.joinable())
+ m_thread.join();
+ return m_isSandboxed;
+ }
+private:
+ bool m_isSandboxed;
+ mutable std::thread m_thread;
+ mutable std::mutex m_mutex;
+};
+} // namespace
+static SandboxChecker sandboxChecker;
+#endif // Q_OS_MACOS
+
bool qt_apple_isSandboxed()
{
#if defined(Q_OS_MACOS)
- static bool isSandboxed = []() {
- QCFType<SecStaticCodeRef> staticCode = nullptr;
- NSURL *executableUrl = NSBundle.mainBundle.executableURL;
- if (SecStaticCodeCreateWithPath((__bridge CFURLRef)executableUrl,
- kSecCSDefaultFlags, &staticCode) != errSecSuccess)
- return false;
-
- QCFType<SecRequirementRef> sandboxRequirement;
- if (SecRequirementCreateWithString(CFSTR("entitlement[\"com.apple.security.app-sandbox\"] exists"),
- kSecCSDefaultFlags, &sandboxRequirement) != errSecSuccess)
- return false;
-
- if (SecStaticCodeCheckValidityWithErrors(staticCode,
- kSecCSBasicValidateOnly, sandboxRequirement, nullptr) != errSecSuccess)
- return false;
-
- return true;
- }();
- return isSandboxed;
+ return sandboxChecker.isSandboxed();
#else
return true; // All other Apple platforms
#endif
}
-#if !defined(QT_BOOTSTRAPPED)
QT_END_NAMESPACE
@implementation NSObject (QtSandboxHelpers)
- (id)qt_valueForPrivateKey:(NSString *)key
@@ -495,7 +527,7 @@ QT_END_NAMESPACE
}
@end
QT_BEGIN_NAMESPACE
-#endif
+#endif // !QT_BOOTSTRAPPED
#ifdef Q_OS_MACOS
/*
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index aee5fcb604..39ffe831bb 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -195,15 +195,18 @@ Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QCFString &string);
#endif
Q_CORE_EXPORT bool qt_apple_isApplicationExtension();
+
+#if !defined(QT_BOOTSTRAPPED)
Q_CORE_EXPORT bool qt_apple_isSandboxed();
-#if !defined(QT_BOOTSTRAPPED) && defined(__OBJC__)
+#if defined(__OBJC__)
QT_END_NAMESPACE
@interface NSObject (QtSandboxHelpers)
- (id)qt_valueForPrivateKey:(NSString *)key;
@end
QT_BEGIN_NAMESPACE
#endif
+#endif // !QT_BOOTSTRAPPED
#if !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WATCHOS)
QT_END_NAMESPACE