FileUtil: Handle app translocation on macOS
This commit is contained in:
parent
c404452d3e
commit
c87241479a
|
@ -20,6 +20,9 @@
|
||||||
#include "Common/CommonFuncs.h"
|
#include "Common/CommonFuncs.h"
|
||||||
#include "Common/CommonPaths.h"
|
#include "Common/CommonPaths.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include "Common/DynamicLibrary.h"
|
||||||
|
#endif
|
||||||
#include "Common/FileUtil.h"
|
#include "Common/FileUtil.h"
|
||||||
#include "Common/IOFile.h"
|
#include "Common/IOFile.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
@ -66,6 +69,18 @@ namespace File
|
||||||
static std::string s_android_sys_directory;
|
static std::string s_android_sys_directory;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
static Common::DynamicLibrary s_security_framework;
|
||||||
|
|
||||||
|
using DolSecTranslocateIsTranslocatedURL = Boolean (*)(CFURLRef path, bool* isTranslocated,
|
||||||
|
CFErrorRef* __nullable error);
|
||||||
|
using DolSecTranslocateCreateOriginalPathForURL = CFURLRef
|
||||||
|
__nullable (*)(CFURLRef translocatedPath, CFErrorRef* __nullable error);
|
||||||
|
|
||||||
|
static DolSecTranslocateIsTranslocatedURL s_is_translocated_url;
|
||||||
|
static DolSecTranslocateCreateOriginalPathForURL s_create_orig_path;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
FileInfo::FileInfo(const std::string& path)
|
FileInfo::FileInfo(const std::string& path)
|
||||||
{
|
{
|
||||||
|
@ -776,16 +791,49 @@ std::string GetTempFilenameForAtomicWrite(std::string path)
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
std::string GetBundleDirectory()
|
std::string GetBundleDirectory()
|
||||||
{
|
{
|
||||||
CFURLRef BundleRef;
|
CFURLRef bundle_ref = CFBundleCopyBundleURL(CFBundleGetMainBundle());
|
||||||
char AppBundlePath[MAXPATHLEN];
|
|
||||||
// Get the main bundle for the app
|
|
||||||
BundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
|
|
||||||
CFStringRef BundlePath = CFURLCopyFileSystemPath(BundleRef, kCFURLPOSIXPathStyle);
|
|
||||||
CFStringGetFileSystemRepresentation(BundlePath, AppBundlePath, sizeof(AppBundlePath));
|
|
||||||
CFRelease(BundleRef);
|
|
||||||
CFRelease(BundlePath);
|
|
||||||
|
|
||||||
return AppBundlePath;
|
// Starting in macOS Sierra, apps downloaded from the Internet may be
|
||||||
|
// "translocated" to a read-only DMG and executed from there. This is
|
||||||
|
// done to prevent a scenario where an attacker can replace a trusted
|
||||||
|
// app's resources to load untrusted code.
|
||||||
|
//
|
||||||
|
// We should return Dolphin's actual location on the filesystem in
|
||||||
|
// this function, so bundle_ref will be untranslocated if necessary.
|
||||||
|
//
|
||||||
|
// More information: https://objective-see.com/blog/blog_0x15.html
|
||||||
|
if (__builtin_available(macOS 10.12, *))
|
||||||
|
{
|
||||||
|
// The APIs to deal with translocated paths are private, so we have
|
||||||
|
// to dynamically load them from the Security framework.
|
||||||
|
//
|
||||||
|
// The headers can be found under "Security" on opensource.apple.com:
|
||||||
|
// Security/OSX/libsecurity_translocate/lib/SecTranslocate.h
|
||||||
|
if (!s_security_framework.IsOpen())
|
||||||
|
{
|
||||||
|
s_security_framework.Open("/System/Library/Frameworks/Security.framework/Security");
|
||||||
|
s_security_framework.GetSymbol("SecTranslocateIsTranslocatedURL", &s_is_translocated_url);
|
||||||
|
s_security_framework.GetSymbol("SecTranslocateCreateOriginalPathForURL", &s_create_orig_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_translocated = false;
|
||||||
|
s_is_translocated_url(bundle_ref, &is_translocated, nullptr);
|
||||||
|
|
||||||
|
if (is_translocated)
|
||||||
|
{
|
||||||
|
CFURLRef untranslocated_ref = s_create_orig_path(bundle_ref, nullptr);
|
||||||
|
CFRelease(bundle_ref);
|
||||||
|
bundle_ref = untranslocated_ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char app_bundle_path[MAXPATHLEN];
|
||||||
|
CFStringRef bundle_path = CFURLCopyFileSystemPath(bundle_ref, kCFURLPOSIXPathStyle);
|
||||||
|
CFStringGetFileSystemRepresentation(bundle_path, app_bundle_path, sizeof(app_bundle_path));
|
||||||
|
CFRelease(bundle_ref);
|
||||||
|
CFRelease(bundle_path);
|
||||||
|
|
||||||
|
return app_bundle_path;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue