macOS: Add private API to ensure that a process is responsible/disclaimed
Useful for tests that request permissions and need to ensure these are requested on behalf of the app itself, and not its parent process, regardless of how it's invoked. Change-Id: Iac493e95440a3a04df4fa466c1d700ba1233e393 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>bb10
parent
c46ee7df57
commit
057cce5e85
|
|
@ -19,6 +19,7 @@
|
|||
#include <objc/runtime.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <spawn.h>
|
||||
|
||||
#include <qdebug.h>
|
||||
|
||||
|
|
@ -33,6 +34,12 @@
|
|||
extern "C" {
|
||||
typedef uint32_t csr_config_t;
|
||||
extern int csr_get_active_config(csr_config_t *) __attribute__((weak_import));
|
||||
|
||||
int responsibility_spawnattrs_setdisclaim(posix_spawnattr_t attrs, int disclaim)
|
||||
__attribute__((availability(macos,introduced=10.14),weak_import));
|
||||
pid_t responsibility_get_pid_responsible_for_pid(pid_t) __attribute__((weak_import));
|
||||
char *** _NSGetArgv();
|
||||
extern char **environ;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -382,6 +389,52 @@ std::optional<uint32_t> qt_mac_sipConfiguration()
|
|||
}();
|
||||
return configuration;
|
||||
}
|
||||
|
||||
#define CHECK_SPAWN(expr) \
|
||||
if (int err = (expr)) { \
|
||||
posix_spawnattr_destroy(&attr); \
|
||||
return; \
|
||||
}
|
||||
|
||||
void qt_mac_ensureResponsible()
|
||||
{
|
||||
#if !defined(QT_APPLE_NO_PRIVATE_APIS)
|
||||
if (!responsibility_get_pid_responsible_for_pid || !responsibility_spawnattrs_setdisclaim)
|
||||
return;
|
||||
|
||||
auto pid = getpid();
|
||||
if (responsibility_get_pid_responsible_for_pid(pid) == pid)
|
||||
return; // Already responsible
|
||||
|
||||
posix_spawnattr_t attr = {};
|
||||
CHECK_SPAWN(posix_spawnattr_init(&attr));
|
||||
|
||||
// Behave as exec
|
||||
short flags = POSIX_SPAWN_SETEXEC;
|
||||
|
||||
// Reset signal mask
|
||||
sigset_t no_signals;
|
||||
sigemptyset(&no_signals);
|
||||
CHECK_SPAWN(posix_spawnattr_setsigmask(&attr, &no_signals));
|
||||
flags |= POSIX_SPAWN_SETSIGMASK;
|
||||
|
||||
// Reset all signals to their default handlers
|
||||
sigset_t all_signals;
|
||||
sigfillset(&all_signals);
|
||||
CHECK_SPAWN(posix_spawnattr_setsigdefault(&attr, &all_signals));
|
||||
flags |= POSIX_SPAWN_SETSIGDEF;
|
||||
|
||||
CHECK_SPAWN(posix_spawnattr_setflags(&attr, flags));
|
||||
|
||||
if (@available(macOS 10.14, *))
|
||||
CHECK_SPAWN(responsibility_spawnattrs_setdisclaim(&attr, 1));
|
||||
|
||||
char **argv = *_NSGetArgv();
|
||||
posix_spawnp(&pid, argv[0], nullptr, &attr, argv, environ);
|
||||
posix_spawnattr_destroy(&attr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool qt_apple_isApplicationExtension()
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ private:
|
|||
Q_CORE_EXPORT bool qt_mac_applicationIsInDarkMode();
|
||||
Q_CORE_EXPORT bool qt_mac_runningUnderRosetta();
|
||||
Q_CORE_EXPORT std::optional<uint32_t> qt_mac_sipConfiguration();
|
||||
Q_CORE_EXPORT void qt_mac_ensureResponsible();
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
|
|
|||
Loading…
Reference in New Issue