summaryrefslogtreecommitdiff
path: root/Source/Core/Common/FileUtil.cpp
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-07-06 02:22:28 +0200
committerGitHub <noreply@github.com>2021-07-06 02:22:28 +0200
commit27c560fdfa182692316d7f0196bd782b11b7744f (patch)
tree6881f3b4808e0b8a515e506b336b2090bdec8072 /Source/Core/Common/FileUtil.cpp
parentccc2b7bd25a625b25c3ab1692f326d96349e37bf (diff)
parent833d5a3e9f6b6a59115ba225c6000747a9bffc93 (diff)
Merge pull request #8915 from OatmealDome/updater-temp-dir
macOS: Untranslocate the app bundle's path for the updater
Diffstat (limited to 'Source/Core/Common/FileUtil.cpp')
-rw-r--r--Source/Core/Common/FileUtil.cpp68
1 files changed, 58 insertions, 10 deletions
diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp
index b7a2ace27e..246452b0bc 100644
--- a/Source/Core/Common/FileUtil.cpp
+++ b/Source/Core/Common/FileUtil.cpp
@@ -20,6 +20,9 @@
#include "Common/CommonFuncs.h"
#include "Common/CommonPaths.h"
#include "Common/CommonTypes.h"
+#ifdef __APPLE__
+#include "Common/DynamicLibrary.h"
+#endif
#include "Common/FileUtil.h"
#include "Common/IOFile.h"
#include "Common/Logging/Log.h"
@@ -66,6 +69,18 @@ namespace File
static std::string s_android_sys_directory;
#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
FileInfo::FileInfo(const std::string& path)
{
@@ -776,16 +791,49 @@ std::string GetTempFilenameForAtomicWrite(std::string path)
#if defined(__APPLE__)
std::string GetBundleDirectory()
{
- CFURLRef BundleRef;
- 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;
+ CFURLRef bundle_ref = CFBundleCopyBundleURL(CFBundleGetMainBundle());
+
+ // 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