We should cache the compiled sandbox profile in a data vault
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Jul 2018 23:44:59 +0000 (23:44 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Jul 2018 23:44:59 +0000 (23:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=184991

Patch by Ben Richards <benton_richards@apple.com> on 2018-07-23
Reviewed by Ryosuke Niwa.

Source/WebCore:

Added functionality to FileHandle so that it can lock a file while open.
Added a function to FileSystem to delete non empty directories.

* platform/FileHandle.cpp:
(WebCore::FileHandle::FileHandle):
(WebCore::FileHandle::open):
(WebCore::FileHandle::close):
* platform/FileHandle.h:
* platform/FileSystem.h:
* platform/cocoa/FileSystemCocoa.mm:
(WebCore::FileSystem::deleteNonEmptyDirectory):

Source/WebKit:

This patch changes a few things (note: data vaults and sandbox entitlements are only used in internal builds):
(1) Instead of compiling a sandbox every time a process is launched, processes now look for a cached sandbox
    in a process specific data vault on macOS platforms. (ChildProcessMac.mm)
(2) If a valid cached sandbox is not found, a process will create the data vault (or ensure that it exists),
    compile a sandbox, and cache it.
(3) In order to create process specific data vaults, each process now has their own <process name>-OSX-sandbox.entitlements
    file which contains an entitlement with a process specific "storage class" which ensures that each process
    can only ever access its own data vault. (See the article on confluence "Data Vaults and Restricted Files" for more info)
(4) The sandbox entitlements file for the Network, WebContent and Plugin services are loaded dynamically
    through Scripts/<process name>-process-entitlements.sh which is triggered in a new build phase for each service.
    The Storage process sandbox entitlements are loaded directly in Configurations/StorageService.xcconfig.
    The reason that the sandbox entitlements are applied dynamically is so that these sandbox entitlements
    are only applied when WK_USE_RESTRICTED_ENTITLEMENTS is YES. This means that open source builds will still work.

* Configurations/Network-OSX-sandbox.entitlements: Added.
* Configurations/Plugin-OSX-sandbox.entitlements: Added.
* Configurations/Storage-OSX-sandbox.entitlements: Added.
* Configurations/StorageService.xcconfig:
* Configurations/WebContent-OSX-sandbox.entitlements: Added.
* Configurations/WebKit.xcconfig:
* NetworkProcess/NetworkProcess.h:
* PluginProcess/PluginProcess.h:
* Scripts/process-network-entitlements.sh: Added.
* Scripts/process-plugin-entitlements.sh: Added.
* Scripts/process-webcontent-entitlements.sh:
* Shared/ChildProcess.h:
* Shared/EntryPointUtilities/mac/XPCService/XPCServiceEntryPoint.h:
(WebKit::XPCServiceInitializer):
* Shared/SandboxInitializationParameters.h:
(WebKit::SandboxInitializationParameters::setOverrideSandboxProfilePath):
(WebKit::SandboxInitializationParameters::overrideSandboxProfilePath const):
(WebKit::SandboxInitializationParameters::setSandboxProfile):
(WebKit::SandboxInitializationParameters::sandboxProfile const):
(): Deleted.
* Shared/mac/ChildProcessMac.mm:
(WebKit::SandboxProfileDeleter::operator()):
(WebKit::SandboxParametersDeleter::operator()):
(WebKit::SandboxInfo::SandboxInfo):
(WebKit::fileContents):
(WebKit::processStorageClass):
(WebKit::setAndSerializeSandboxParameters):
(WebKit::getUserCacheDirectory):
(WebKit::sandboxDataVaultParentDirectory):
(WebKit::sandboxDirectory):
(WebKit::sandboxFilePath):
(WebKit::ensureSandboxCacheDirectory):
(WebKit::writeSandboxDataToCacheFile):
(WebKit::compileAndCacheSandboxProfile):
(WebKit::tryApplyCachedSandbox):
(WebKit::webKit2Bundle):
(WebKit::sandboxProfilePath):
(WebKit::compileAndApplySandboxSlowCase):
(WebKit::applySandbox):
(WebKit::initializeSandboxParameters):
(WebKit::ChildProcess::initializeSandbox):
* Shared/mac/SandboxInitialiationParametersMac.mm:
(WebKit::SandboxInitializationParameters::SandboxInitializationParameters):
* StorageProcess/StorageProcess.h:
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/WebProcess.h:

Source/WTF:

Added trace points for sandbox initialization and exposed functions needed for sandbox caching

* wtf/SystemTracing.h:
* wtf/spi/darwin/SandboxSPI.h:

Tools:

Added trace points for sandbox initialization

* Tracing/SystemTracePoints.plist:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234121 268f45cc-cd09-0410-ab3c-d52691b4dbfc

30 files changed:
Source/WTF/ChangeLog
Source/WTF/wtf/SystemTracing.h
Source/WTF/wtf/spi/darwin/SandboxSPI.h
Source/WebCore/ChangeLog
Source/WebCore/platform/FileHandle.cpp
Source/WebCore/platform/FileHandle.h
Source/WebCore/platform/FileSystem.h
Source/WebCore/platform/cocoa/FileSystemCocoa.mm
Source/WebKit/ChangeLog
Source/WebKit/Configurations/Network-OSX-sandbox.entitlements [new file with mode: 0644]
Source/WebKit/Configurations/Plugin-OSX-sandbox.entitlements [new file with mode: 0644]
Source/WebKit/Configurations/Storage-OSX-sandbox.entitlements [new file with mode: 0644]
Source/WebKit/Configurations/StorageService.xcconfig
Source/WebKit/Configurations/WebContent-OSX-sandbox.entitlements [new file with mode: 0644]
Source/WebKit/Configurations/WebKit.xcconfig
Source/WebKit/NetworkProcess/NetworkProcess.h
Source/WebKit/PluginProcess/PluginProcess.h
Source/WebKit/Scripts/process-network-entitlements.sh [new file with mode: 0755]
Source/WebKit/Scripts/process-plugin-entitlements.sh [new file with mode: 0755]
Source/WebKit/Scripts/process-webcontent-entitlements.sh
Source/WebKit/Shared/ChildProcess.h
Source/WebKit/Shared/EntryPointUtilities/mac/XPCService/XPCServiceEntryPoint.h
Source/WebKit/Shared/SandboxInitializationParameters.h
Source/WebKit/Shared/mac/ChildProcessMac.mm
Source/WebKit/Shared/mac/SandboxInitialiationParametersMac.mm
Source/WebKit/StorageProcess/StorageProcess.h
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/WebProcess/WebProcess.h
Tools/ChangeLog
Tools/Tracing/SystemTracePoints.plist

index ccd6d53..eacbf3c 100644 (file)
@@ -1,3 +1,15 @@
+2018-07-23  Ben Richards  <benton_richards@apple.com>
+
+        We should cache the compiled sandbox profile in a data vault
+        https://bugs.webkit.org/show_bug.cgi?id=184991
+
+        Reviewed by Ryosuke Niwa.
+
+        Added trace points for sandbox initialization and exposed functions needed for sandbox caching
+
+        * wtf/SystemTracing.h:
+        * wtf/spi/darwin/SandboxSPI.h:
+
 2018-06-06  Filip Pizlo  <fpizlo@apple.com>
 
         We should support CreateThis in the FTL
index b52be8d..105196e 100644 (file)
@@ -96,6 +96,8 @@ enum TracePointCode {
     CommitLayerTreeEnd,
     ProcessLaunchStart,
     ProcessLaunchEnd,
+    InitializeSandboxStart,
+    InitializeSandboxEnd,
 };
 
 #ifdef __cplusplus
index fa18c9e..1c3c595 100644 (file)
@@ -42,6 +42,18 @@ enum sandbox_filter_type {
 
 WTF_EXTERN_C_BEGIN
 
+typedef struct {
+    char* builtin;
+    unsigned char* data;
+    size_t size;
+} *sandbox_profile_t;
+
+typedef struct {
+    const char **params;
+    size_t size;
+    size_t available;
+} *sandbox_params_t;
+
 extern const char *const APP_SANDBOX_READ;
 extern const char *const APP_SANDBOX_READ_WRITE;
 extern const enum sandbox_filter_type SANDBOX_CHECK_NO_REPORT;
@@ -54,6 +66,12 @@ int sandbox_container_path_for_pid(pid_t, char *buffer, size_t bufsize);
 int sandbox_extension_release(int64_t extension_handle);
 int sandbox_init_with_parameters(const char *profile, uint64_t flags, const char *const parameters[], char **errorbuf);
 int64_t sandbox_extension_consume(const char *extension_token);
+sandbox_params_t sandbox_create_params(void);
+int sandbox_set_param(sandbox_params_t, const char *key, const char *value);
+void sandbox_free_params(sandbox_params_t);
+sandbox_profile_t sandbox_compile_file(const char *path, sandbox_params_t, char **error);
+void sandbox_free_profile(sandbox_profile_t);
+int sandbox_apply(sandbox_profile_t);
 
 WTF_EXTERN_C_END
 
index 594642a..6beb0bd 100644 (file)
@@ -1,3 +1,22 @@
+2018-07-23  Ben Richards  <benton_richards@apple.com>
+
+        We should cache the compiled sandbox profile in a data vault
+        https://bugs.webkit.org/show_bug.cgi?id=184991
+
+        Reviewed by Ryosuke Niwa.
+
+        Added functionality to FileHandle so that it can lock a file while open.
+        Added a function to FileSystem to delete non empty directories.
+
+        * platform/FileHandle.cpp:
+        (WebCore::FileHandle::FileHandle):
+        (WebCore::FileHandle::open):
+        (WebCore::FileHandle::close):
+        * platform/FileHandle.h:
+        * platform/FileSystem.h:
+        * platform/cocoa/FileSystemCocoa.mm:
+        (WebCore::FileSystem::deleteNonEmptyDirectory):
+
 2018-07-23  Justin Fan  <justin_fan@apple.com>
 
         [macOS] Ensure that WebGL contexts are always set to an accelerated virtual screen
index 1c3f532..ebe6562 100644 (file)
 namespace WebCore {
 
 FileHandle::FileHandle(const String& path, FileSystem::FileOpenMode mode)
-    : m_path(path)
-    , m_mode(mode)
+    : m_path { path }
+    , m_mode { mode }
 {
 }
 
 FileHandle::FileHandle(FileHandle&& other)
-    : m_path(WTFMove(other.m_path))
-    , m_mode(WTFMove(other.m_mode))
-    , m_fileHandle(std::exchange(other.m_fileHandle, FileSystem::invalidPlatformFileHandle))
+    : m_path { WTFMove(other.m_path) }
+    , m_mode { WTFMove(other.m_mode) }
+    , m_fileHandle { std::exchange(other.m_fileHandle, FileSystem::invalidPlatformFileHandle) }
+{
+}
+    
+FileHandle::FileHandle(const String& path, FileSystem::FileOpenMode mode, OptionSet<FileSystem::FileLockMode> lockMode)
+    : m_path { path }
+    , m_mode { mode }
+    , m_shouldLock { true }
+    , m_lockMode { lockMode }
 {
 }
 
@@ -77,7 +85,7 @@ bool FileHandle::open(const String& path, FileSystem::FileOpenMode mode)
 bool FileHandle::open()
 {
     if (!*this)
-        m_fileHandle = FileSystem::openFile(m_path, m_mode);
+        m_fileHandle = m_shouldLock ? FileSystem::openAndLockFile(m_path, m_mode, m_lockMode) :  FileSystem::openFile(m_path, m_mode);
     return static_cast<bool>(*this);
 }
 
@@ -115,7 +123,11 @@ bool FileHandle::printf(const char* format, ...)
 
 void FileHandle::close()
 {
-    FileSystem::closeFile(m_fileHandle);
+    if (m_shouldLock && *this) {
+        // FileSystem::unlockAndCloseFile requires the file handle to be valid while closeFile does not
+        FileSystem::unlockAndCloseFile(m_fileHandle);
+    } else
+        FileSystem::closeFile(m_fileHandle);
 }
 
 } // namespace WebCore
index 659422a..5ff8a43 100644 (file)
@@ -38,6 +38,7 @@ class WEBCORE_EXPORT FileHandle final {
 public:
     FileHandle() = default;
     FileHandle(const String& path, FileSystem::FileOpenMode);
+    FileHandle(const String& path, FileSystem::FileOpenMode, OptionSet<FileSystem::FileLockMode>);
     FileHandle(const FileHandle& other) = delete;
     FileHandle(FileHandle&& other);
 
@@ -59,6 +60,8 @@ private:
     String m_path;
     FileSystem::FileOpenMode m_mode { FileSystem::FileOpenMode::Read };
     FileSystem::PlatformFileHandle m_fileHandle { FileSystem::invalidPlatformFileHandle };
+    bool m_shouldLock { false };
+    OptionSet<FileSystem::FileLockMode> m_lockMode;
 };
 
 } // namespace WebCore
index 808f9a4..a52ab4c 100644 (file)
@@ -184,6 +184,7 @@ String roamingUserSpecificStorageDirectory();
 
 #if PLATFORM(COCOA)
 WEBCORE_EXPORT NSString *createTemporaryDirectory(NSString *directoryPrefix);
+WEBCORE_EXPORT bool deleteNonEmptyDirectory(const String&);
 #endif
 
 WEBCORE_EXPORT String realPath(const String&);
index 6a2924d..c53d84b 100644 (file)
@@ -133,6 +133,11 @@ NSString *createTemporaryDirectory(NSString *directoryPrefix)
 
     return [[NSFileManager defaultManager] stringWithFileSystemRepresentation:path.data() length:length];
 }
+    
+bool deleteNonEmptyDirectory(const String& path)
+{
+    return [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
+}
 
 } // namespace FileSystem
 } // namespace WebCore
index 253d637..249c934 100644 (file)
@@ -1,3 +1,71 @@
+2018-07-23  Ben Richards  <benton_richards@apple.com>
+
+        We should cache the compiled sandbox profile in a data vault
+        https://bugs.webkit.org/show_bug.cgi?id=184991
+
+        Reviewed by Ryosuke Niwa.
+
+        This patch changes a few things (note: data vaults and sandbox entitlements are only used in internal builds):
+        (1) Instead of compiling a sandbox every time a process is launched, processes now look for a cached sandbox
+            in a process specific data vault on macOS platforms. (ChildProcessMac.mm)
+        (2) If a valid cached sandbox is not found, a process will create the data vault (or ensure that it exists),
+            compile a sandbox, and cache it.
+        (3) In order to create process specific data vaults, each process now has their own <process name>-OSX-sandbox.entitlements
+            file which contains an entitlement with a process specific "storage class" which ensures that each process
+            can only ever access its own data vault. (See the article on confluence "Data Vaults and Restricted Files" for more info)
+        (4) The sandbox entitlements file for the Network, WebContent and Plugin services are loaded dynamically
+            through Scripts/<process name>-process-entitlements.sh which is triggered in a new build phase for each service.
+            The Storage process sandbox entitlements are loaded directly in Configurations/StorageService.xcconfig.
+            The reason that the sandbox entitlements are applied dynamically is so that these sandbox entitlements
+            are only applied when WK_USE_RESTRICTED_ENTITLEMENTS is YES. This means that open source builds will still work.
+
+        * Configurations/Network-OSX-sandbox.entitlements: Added.
+        * Configurations/Plugin-OSX-sandbox.entitlements: Added.
+        * Configurations/Storage-OSX-sandbox.entitlements: Added.
+        * Configurations/StorageService.xcconfig:
+        * Configurations/WebContent-OSX-sandbox.entitlements: Added.
+        * Configurations/WebKit.xcconfig:
+        * NetworkProcess/NetworkProcess.h:
+        * PluginProcess/PluginProcess.h:
+        * Scripts/process-network-entitlements.sh: Added.
+        * Scripts/process-plugin-entitlements.sh: Added.
+        * Scripts/process-webcontent-entitlements.sh:
+        * Shared/ChildProcess.h:
+        * Shared/EntryPointUtilities/mac/XPCService/XPCServiceEntryPoint.h:
+        (WebKit::XPCServiceInitializer):
+        * Shared/SandboxInitializationParameters.h:
+        (WebKit::SandboxInitializationParameters::setOverrideSandboxProfilePath):
+        (WebKit::SandboxInitializationParameters::overrideSandboxProfilePath const):
+        (WebKit::SandboxInitializationParameters::setSandboxProfile):
+        (WebKit::SandboxInitializationParameters::sandboxProfile const):
+        (): Deleted.
+        * Shared/mac/ChildProcessMac.mm:
+        (WebKit::SandboxProfileDeleter::operator()):
+        (WebKit::SandboxParametersDeleter::operator()):
+        (WebKit::SandboxInfo::SandboxInfo):
+        (WebKit::fileContents):
+        (WebKit::processStorageClass):
+        (WebKit::setAndSerializeSandboxParameters):
+        (WebKit::getUserCacheDirectory):
+        (WebKit::sandboxDataVaultParentDirectory):
+        (WebKit::sandboxDirectory):
+        (WebKit::sandboxFilePath):
+        (WebKit::ensureSandboxCacheDirectory):
+        (WebKit::writeSandboxDataToCacheFile):
+        (WebKit::compileAndCacheSandboxProfile):
+        (WebKit::tryApplyCachedSandbox):
+        (WebKit::webKit2Bundle):
+        (WebKit::sandboxProfilePath):
+        (WebKit::compileAndApplySandboxSlowCase):
+        (WebKit::applySandbox):
+        (WebKit::initializeSandboxParameters):
+        (WebKit::ChildProcess::initializeSandbox):
+        * Shared/mac/SandboxInitialiationParametersMac.mm:
+        (WebKit::SandboxInitializationParameters::SandboxInitializationParameters):
+        * StorageProcess/StorageProcess.h:
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/WebProcess.h:
+
 2018-07-23  Tim Horton  <timothy_horton@apple.com>
 
         Creating and loading content in a WKWebView triggers Main Thread Checker warnings under ServicesController
diff --git a/Source/WebKit/Configurations/Network-OSX-sandbox.entitlements b/Source/WebKit/Configurations/Network-OSX-sandbox.entitlements
new file mode 100644 (file)
index 0000000..0327056
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>com.apple.rootless.storage.WebKitNetworkingSandbox</key>
+       <true/>
+</dict>
+</plist>
diff --git a/Source/WebKit/Configurations/Plugin-OSX-sandbox.entitlements b/Source/WebKit/Configurations/Plugin-OSX-sandbox.entitlements
new file mode 100644 (file)
index 0000000..d653b21
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>com.apple.rootless.storage.WebKitPluginSandbox</key>
+       <true/>
+</dict>
+</plist>
diff --git a/Source/WebKit/Configurations/Storage-OSX-sandbox.entitlements b/Source/WebKit/Configurations/Storage-OSX-sandbox.entitlements
new file mode 100644 (file)
index 0000000..bbb392e
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>com.apple.rootless.storage.WebKitStorageSandbox</key>
+       <true/>
+</dict>
+</plist>
index 75761d8..5d51209 100644 (file)
 
 WK_XPC_SERVICE_IOS_ENTITLEMENTS_BASE = Databases-iOS;
 
+WK_STORAGE_ENTITLEMENTS_RESTRICTED_NO = ;
+WK_STORAGE_ENTITLEMENTS_RESTRICTED_YES = Configurations/Storage-OSX-sandbox.entitlements;
+
+CODE_SIGN_ENTITLEMENTS_COCOA_TOUCH_NO = $(WK_STORAGE_ENTITLEMENTS_RESTRICTED_$(WK_USE_RESTRICTED_ENTITLEMENTS));
 OTHER_CODE_SIGN_FLAGS = $(WK_LIBRARY_VALIDATION_CODE_SIGN_FLAGS);
 
 PRODUCT_NAME = $(WK_STORAGE_SERVICE_PRODUCT_NAME);
diff --git a/Source/WebKit/Configurations/WebContent-OSX-sandbox.entitlements b/Source/WebKit/Configurations/WebContent-OSX-sandbox.entitlements
new file mode 100644 (file)
index 0000000..c34363a
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>com.apple.rootless.storage.WebKitWebContentSandbox</key>
+       <true/>
+</dict>
+</plist>
index 3cee43c..a66709f 100644 (file)
@@ -82,6 +82,9 @@ WK_MOBILE_CORE_SERVICES_LDFLAGS_cocoatouch = -framework MobileCoreServices;
 WK_MOBILE_GESTALT_LDFLAGS = $(WK_MOBILE_GESTALT_LDFLAGS_$(WK_COCOA_TOUCH));
 WK_MOBILE_GESTALT_LDFLAGS_cocoatouch = -lMobileGestalt;
 
+WK_LIBSANDBOX_LDFLAGS = $(WK_LIBSANDBOX_LDFLAGS_$(WK_PLATFORM_NAME));
+WK_LIBSANDBOX_LDFLAGS_macosx = -lsandbox;
+
 WK_OPENGL_LDFLAGS = $(WK_OPENGL_LDFLAGS_$(WK_PLATFORM_NAME));
 WK_OPENGL_LDFLAGS_iphoneos = -framework OpenGLES;
 WK_OPENGL_LDFLAGS_iosmac = -framework OpenGL;
@@ -112,7 +115,7 @@ WK_UIKIT_LDFLAGS_cocoatouch = -framework UIKit;
 WK_URL_FORMATTING_LDFLAGS = $(WK_URL_FORMATTING_LDFLAGS_$(WK_HAVE_URL_FORMATTING));
 WK_URL_FORMATTING_LDFLAGS_YES = -framework URLFormatting;
 
-FRAMEWORK_AND_LIBRARY_LDFLAGS = -lobjc -framework CFNetwork -framework CoreAudio -framework CoreFoundation -framework CoreGraphics -framework CoreText -framework Foundation -framework ImageIO -framework IOKit -framework WebKitLegacy -lnetwork $(WK_ACCESSIBILITY_LDFLAGS) $(WK_APPKIT_LDFLAGS) $(WK_ASSERTION_SERVICES_LDFLAGS) $(WK_CARBON_LDFLAGS) $(WK_CORE_PDF_LDFLAGS) $(WK_CORE_PREDICTION_LDFLAGS) $(WK_CORE_SERVICES_LDFLAGS) $(WK_GRAPHICS_SERVICES_LDFLAGS) $(WK_IOSURFACE_LDFLAGS) $(WK_LIBWEBRTC_LDFLAGS) $(WK_MOBILE_CORE_SERVICES_LDFLAGS) $(WK_MOBILE_GESTALT_LDFLAGS) $(WK_OPENGL_LDFLAGS) $(WK_PDFKIT_LDFLAGS) $(WK_SAFE_BROWSING_LDFLAGS) $(WK_UIKIT_LDFLAGS) $(WK_URL_FORMATTING_LDFLAGS);
+FRAMEWORK_AND_LIBRARY_LDFLAGS = -lobjc -framework CFNetwork -framework CoreAudio -framework CoreFoundation -framework CoreGraphics -framework CoreText -framework Foundation -framework ImageIO -framework IOKit -framework WebKitLegacy -lnetwork $(WK_ACCESSIBILITY_LDFLAGS) $(WK_APPKIT_LDFLAGS) $(WK_ASSERTION_SERVICES_LDFLAGS) $(WK_CARBON_LDFLAGS) $(WK_CORE_PDF_LDFLAGS) $(WK_CORE_PREDICTION_LDFLAGS) $(WK_CORE_SERVICES_LDFLAGS) $(WK_GRAPHICS_SERVICES_LDFLAGS) $(WK_IOSURFACE_LDFLAGS) $(WK_LIBSANDBOX_LDFLAGS) $(WK_LIBWEBRTC_LDFLAGS) $(WK_MOBILE_CORE_SERVICES_LDFLAGS) $(WK_MOBILE_GESTALT_LDFLAGS) $(WK_OPENGL_LDFLAGS) $(WK_PDFKIT_LDFLAGS) $(WK_SAFE_BROWSING_LDFLAGS) $(WK_UIKIT_LDFLAGS) $(WK_URL_FORMATTING_LDFLAGS);
 
 // Prevent C++ standard library basic_stringstream, operator new, delete and their related exception types from being exported as weak symbols.
 UNEXPORTED_SYMBOL_LDFLAGS = -Wl,-unexported_symbol -Wl,__ZTISt9bad_alloc -Wl,-unexported_symbol -Wl,__ZTISt9exception -Wl,-unexported_symbol -Wl,__ZTSSt9bad_alloc -Wl,-unexported_symbol -Wl,__ZTSSt9exception -Wl,-unexported_symbol -Wl,__ZdlPvS_ -Wl,-unexported_symbol -Wl,__ZnwmPv -Wl,-unexported_symbol -Wl,__Znwm -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEEC2EOS4_ -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEEC1EOS4_ -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEEaSEDn -Wl,-unexported_symbol -Wl,__ZNKSt3__18functionIFvN7WebCore12PolicyActionEEEclES2_ -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEE4swapERS4_ -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEEC1ERKS4_ -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEEC2ERKS4_ -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEED1Ev -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEED2Ev -Wl,-unexported_symbol -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEEaSERKS4_ -Wl,-unexported_symbol -Wl,__ZTVNSt3__117bad_function_callE -Wl,-unexported_symbol -Wl,__ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_13basic_istreamIcS2_EE -Wl,-unexported_symbol -Wl,__ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_14basic_iostreamIcS2_EE -Wl,-unexported_symbol -Wl,__ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE16_NS_13basic_ostreamIcS2_EE -Wl,-unexported_symbol -Wl,__ZTTNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE -Wl,-unexported_symbol -Wl,__ZTVNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEE -Wl,-unexported_symbol -Wl,__ZTVNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE -Wl,-unexported_symbol -Wl,__ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE8_NS_13basic_ostreamIcS2_EE;
index 879d513..09b101d 100644 (file)
@@ -80,6 +80,7 @@ class NetworkProcess : public ChildProcess, private DownloadManager::Client {
     friend NeverDestroyed<DownloadManager>;
 public:
     static NetworkProcess& singleton();
+    static constexpr ProcessType processType = ProcessType::Network;
 
     template <typename T>
     T* supplement()
index 80fd3f3..1157437 100644 (file)
@@ -49,6 +49,7 @@ class PluginProcess : public ChildProcess
 
 public:
     static PluginProcess& singleton();
+    static constexpr ProcessType processType = ProcessType::Plugin;
 
     void removeWebProcessConnection(WebProcessConnection*);
 
diff --git a/Source/WebKit/Scripts/process-network-entitlements.sh b/Source/WebKit/Scripts/process-network-entitlements.sh
new file mode 100755 (executable)
index 0000000..05abfeb
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+set -e
+
+PROCESSED_XCENT_FILE="${TEMP_FILE_DIR}/${FULL_PRODUCT_NAME}.xcent"
+
+if [[ ${WK_PLATFORM_NAME} == "macosx" ]]; then
+
+    if [[ ${WK_USE_RESTRICTED_ENTITLEMENTS} == "YES" ]]; then
+        echo "Processing restricted entitlements for Internal SDK";
+
+        echo "Adding sandbox entitlements for Network process.";
+        /usr/libexec/PlistBuddy -c "Merge Configurations/Network-OSX-sandbox.entitlements" "${PROCESSED_XCENT_FILE}";
+    fi
+fi
diff --git a/Source/WebKit/Scripts/process-plugin-entitlements.sh b/Source/WebKit/Scripts/process-plugin-entitlements.sh
new file mode 100755 (executable)
index 0000000..30d9ca7
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+set -e
+
+PROCESSED_XCENT_FILE="${TEMP_FILE_DIR}/${FULL_PRODUCT_NAME}.xcent"
+
+if [[ ${WK_PLATFORM_NAME} == "macosx" ]]; then
+
+    if [[ ${WK_USE_RESTRICTED_ENTITLEMENTS} == "YES" ]]; then
+        echo "Processing restricted entitlements for Internal SDK";
+
+        echo "Adding sandbox entitlements for Plugin process.";
+        /usr/libexec/PlistBuddy -c "Merge Configurations/Plugin-OSX-sandbox.entitlements" "${PROCESSED_XCENT_FILE}";
+    fi
+fi
index 1900322..618e4d2 100755 (executable)
@@ -8,6 +8,9 @@ if [[ ${WK_PLATFORM_NAME} == "macosx" ]]; then
     if [[ ${WK_USE_RESTRICTED_ENTITLEMENTS} == "YES" ]]; then
         echo "Processing restricted entitlements for Internal SDK";
 
+        echo "Adding sandbox entitlements for WebContent process.";
+        /usr/libexec/PlistBuddy -c "Merge Configurations/WebContent-OSX-sandbox.entitlements" "${PROCESSED_XCENT_FILE}";
+
         if (( ${TARGET_MAC_OS_X_VERSION_MAJOR} >= 101400 )); then
             echo "Adding macOS platform entitlements.";
             /usr/libexec/PlistBuddy -c "Merge Configurations/WebContent-OSX-restricted.entitlements" "${PROCESSED_XCENT_FILE}";
index a28772b..6524d66 100644 (file)
 namespace WebKit {
 
 class SandboxInitializationParameters;
-
-struct ChildProcessInitializationParameters {
-    String uiProcessName;
-    String clientIdentifier;
-    std::optional<WebCore::ProcessIdentifier> processIdentifier;
-    IPC::Connection::Identifier connectionIdentifier;
-    HashMap<String, String> extraInitializationData;
-#if PLATFORM(COCOA)
-    OSObjectPtr<xpc_object_t> priorityBoostMessage;
-#endif
-};
+struct ChildProcessInitializationParameters;
 
 class ChildProcess : protected IPC::Connection::Client, public IPC::MessageSender {
     WTF_MAKE_NONCOPYABLE(ChildProcess);
 
 public:
+    enum class ProcessType : uint8_t {
+        WebContent,
+        Network,
+        Storage,
+        Plugin
+    };
+
     void initialize(const ChildProcessInitializationParameters&);
 
     // disable and enable termination of the process. when disableTermination is called, the
@@ -149,6 +146,18 @@ private:
 #endif
 };
 
+struct ChildProcessInitializationParameters {
+    String uiProcessName;
+    String clientIdentifier;
+    std::optional<WebCore::ProcessIdentifier> processIdentifier;
+    IPC::Connection::Identifier connectionIdentifier;
+    HashMap<String, String> extraInitializationData;
+    ChildProcess::ProcessType processType;
+#if PLATFORM(COCOA)
+    OSObjectPtr<xpc_object_t> priorityBoostMessage;
+#endif
+};
+
 } // namespace WebKit
 
 #endif // ChildProcess_h
index 5e7ca9e..f5e9564 100644 (file)
@@ -112,6 +112,8 @@ void XPCServiceInitializer(OSObjectPtr<xpc_connection_t> connection, xpc_object_
         Thread::setGlobalMaxQOSClass(QOS_CLASS_UTILITY);
 #endif
 
+    parameters.processType = XPCServiceType::processType;
+
     XPCServiceType::singleton().initialize(parameters);
 }
 
index a619b70..b931095 100644 (file)
@@ -54,7 +54,7 @@ public:
     const char* name(size_t index) const;
     const char* value(size_t index) const;
 
-    enum ProfileSelectionMode {
+    enum class ProfileSelectionMode : uint8_t {
         UseDefaultSandboxProfilePath,
         UseOverrideSandboxProfilePath,
         UseSandboxProfile
@@ -64,25 +64,25 @@ public:
 
     void setOverrideSandboxProfilePath(const String& path)
     {
-        m_profileSelectionMode = UseOverrideSandboxProfilePath;
+        m_profileSelectionMode = ProfileSelectionMode::UseOverrideSandboxProfilePath;
         m_overrideSandboxProfilePathOrSandboxProfile = path;
     }
 
     const String& overrideSandboxProfilePath() const
     {
-        ASSERT(m_profileSelectionMode == UseOverrideSandboxProfilePath);
+        ASSERT(m_profileSelectionMode == ProfileSelectionMode::UseOverrideSandboxProfilePath);
         return m_overrideSandboxProfilePathOrSandboxProfile;
     }
 
     void setSandboxProfile(const String& profile)
     {
-        m_profileSelectionMode = UseSandboxProfile;
+        m_profileSelectionMode = ProfileSelectionMode::UseSandboxProfile;
         m_overrideSandboxProfilePathOrSandboxProfile = profile;
     }
 
     const String& sandboxProfile() const
     {
-        ASSERT(m_profileSelectionMode == UseSandboxProfile);
+        ASSERT(m_profileSelectionMode == ProfileSelectionMode::UseSandboxProfile);
         return m_overrideSandboxProfilePathOrSandboxProfile;
     }
 
index b085ff9..4e34cc5 100644 (file)
 #import "CodeSigning.h"
 #import "QuarantineSPI.h"
 #import "SandboxInitializationParameters.h"
+#import "SandboxUtilities.h"
 #import "WKFoundation.h"
 #import "XPCServiceEntryPoint.h"
+#import <WebCore/FileHandle.h>
 #import <WebCore/FileSystem.h>
 #import <WebCore/SystemVersion.h>
+#import <mach-o/dyld.h>
 #import <mach/mach.h>
 #import <mach/task.h>
+#import <pal/crypto/CryptoDigest.h>
 #import <pwd.h>
 #import <stdlib.h>
+#import <sys/sysctl.h>
 #import <sysexits.h>
+#import <wtf/DataLog.h>
+#import <wtf/RandomNumber.h>
 #import <wtf/Scope.h>
+#import <wtf/SystemTracing.h>
+#import <wtf/WallTime.h>
 #import <wtf/spi/darwin/SandboxSPI.h>
+#import <wtf/text/Base64.h>
+#import <wtf/text/StringBuilder.h>
 
 #if USE(APPLE_INTERNAL_SDK)
-#include <HIServices/ProcessesPriv.h>
+#import <HIServices/ProcessesPriv.h>
+#import <rootless.h>
 #endif
 
 typedef bool (^LSServerConnectionAllowedBlock) ( CFDictionaryRef optionsRef );
@@ -57,6 +69,64 @@ using namespace WebCore;
 
 namespace WebKit {
 
+using SandboxProfile = typename std::remove_pointer<sandbox_profile_t>::type;
+struct SandboxProfileDeleter {
+    void operator()(SandboxProfile* ptr)
+    {
+        sandbox_free_profile(ptr);
+    }
+};
+using SandboxProfilePtr = std::unique_ptr<SandboxProfile, SandboxProfileDeleter>;
+    
+using SandboxParameters = typename std::remove_pointer<sandbox_params_t>::type;
+struct SandboxParametersDeleter {
+    void operator()(SandboxParameters* ptr)
+    {
+        sandbox_free_params(ptr);
+    }
+};
+using SandboxParametersPtr = std::unique_ptr<SandboxParameters, SandboxParametersDeleter>;
+
+struct CachedSandboxHeader {
+    uint32_t versionNumber;
+    uint32_t libsandboxVersion;
+    uint32_t headerSize;
+    uint32_t builtinSize; // If a builtin doesn't exist, this is UINT_MAX.
+    uint32_t dataSize;
+};
+// The file is layed out on disk like:
+// byte 0
+// CachedSandboxHeader <- sizeof(CachedSandboxHeader) bytes
+// SandboxHeader <- CachedSandboxHeader::headerSize bytes
+// [SandboxBuiltin] optional. Present if CachedSandboxHeader::builtinSize is not UINT_MAX. If present, builtinSize bytes (not including null termination).
+// SandboxData <- CachedSandboxHeader::dataSize bytes
+// byte N
+
+struct SandboxInfo {
+    SandboxInfo(const String& parentDirectoryPath, const String& directoryPath, const String& filePath, const String& profilePath, const SandboxParametersPtr& sandboxParameters, const CString& header, const ChildProcess::ProcessType& processType, const SandboxInitializationParameters& initializationParameters)
+        : parentDirectoryPath { parentDirectoryPath }
+        , directoryPath { directoryPath }
+        , filePath { filePath }
+        , profilePath { profilePath }
+        , sandboxParameters { sandboxParameters }
+        , header { header }
+        , processType { processType }
+        , initializationParameters { initializationParameters }
+    {
+    }
+    
+    const String& parentDirectoryPath;
+    const String& directoryPath;
+    const String& filePath;
+    const String& profilePath;
+    const SandboxParametersPtr& sandboxParameters;
+    const CString& header;
+    const ChildProcess::ProcessType& processType;
+    const SandboxInitializationParameters& initializationParameters;
+};
+
+constexpr uint32_t CachedSandboxVersionNumber = 0;
+
 static void initializeTimerCoalescingPolicy()
 {
     // Set task_latency and task_throughput QOS tiers as appropriate for a visible application.
@@ -112,15 +182,412 @@ static OSStatus enableSandboxStyleFileQuarantine()
 #endif
 }
 
-void ChildProcess::initializeSandbox(const ChildProcessInitializationParameters& parameters, SandboxInitializationParameters& sandboxParameters)
+static std::optional<Vector<char>> fileContents(const String& path, bool shouldLock = false, OptionSet<FileSystem::FileLockMode> lockMode = FileSystem::FileLockMode::Exclusive)
+{
+    FileHandle file = shouldLock ? FileHandle(path, FileSystem::FileOpenMode::Read, lockMode) : FileHandle(path, FileSystem::FileOpenMode::Read);
+    file.open();
+    if (!file)
+        return std::nullopt;
+    
+    char chunk[4096];
+    constexpr size_t chunkSize = WTF_ARRAY_LENGTH(chunk);
+    size_t contentSize = 0;
+    Vector<char> contents;
+    contents.reserveInitialCapacity(chunkSize);
+    while (size_t bytesRead = file.read(chunk, chunkSize)) {
+        contents.append(chunk, bytesRead);
+        contentSize += bytesRead;
+    }
+    contents.resize(contentSize);
+    
+    return contents;
+}
+
+#if USE(APPLE_INTERNAL_SDK)
+// These strings must match the last segment of the "com.apple.rootless.storage.<this part must match>" entry in each
+// process's restricted entitlements file (ex. Configurations/Networking-OSX-restricted.entitlements).
+constexpr const char* processStorageClass(ChildProcess::ProcessType type)
+{
+    switch (type) {
+    case ChildProcess::ProcessType::WebContent:
+        return "WebKitWebContentSandbox";
+    case ChildProcess::ProcessType::Network:
+        return "WebKitNetworkingSandbox";
+    case ChildProcess::ProcessType::Storage:
+        return "WebKitStorageSandbox";
+    case ChildProcess::ProcessType::Plugin:
+        return "WebKitPluginSandbox";
+    }
+}
+#endif
+
+static std::optional<CString> setAndSerializeSandboxParameters(const SandboxInitializationParameters& initializationParameters, const SandboxParametersPtr& sandboxParameters, const String& profilePath)
+{
+    StringBuilder builder;
+    for (size_t i = 0; i < initializationParameters.count(); ++i) {
+        CString name = initializationParameters.name(i);
+        CString value = initializationParameters.value(i);
+        if (name.isNull() || value.isNull())
+            return std::nullopt;
+        if (sandbox_set_param(sandboxParameters.get(), name.data(), value.data())) {
+            WTFLogAlways("%s: Couldn't set sandbox parameter, errno: %d\n", getprogname(), errno);
+            CRASH();
+        }
+        builder.append(name.data(), name.length());
+        builder.append(':');
+        builder.append(value.data(), value.length());
+        builder.append(':');
+    }
+    auto contents = fileContents(profilePath);
+    if (!contents)
+        return std::nullopt;
+    builder.append(contents->data(), contents->size());
+    return builder.toString().ascii();
+}
+    
+static size_t getUserCacheDirectory(Vector<char>& buffer)
+{
+    size_t result = confstr(_CS_DARWIN_USER_CACHE_DIR, buffer.data(), buffer.size());
+    if (!result) {
+        WTFLogAlways("%s: couldn't retrieve private cache directory path: %d\n", getprogname(), errno);
+        exit(EX_NOPERM);
+    }
+    return result;
+}
+
+static inline String sandboxDataVaultParentDirectory()
+{
+    // DIRHELPER_USER_DIR_SUFFIX is set in initializeSandboxParameters (called before this function).
+    char parentDirectory[PATH_MAX];
+    
+    Vector<char> temp;
+    temp.grow(PATH_MAX);
+    
+    size_t neededBufferSize = getUserCacheDirectory(temp);
+    if (neededBufferSize > temp.size()) {
+        temp.grow(neededBufferSize);
+        size_t bufferSize = getUserCacheDirectory(temp);
+        RELEASE_ASSERT(bufferSize == temp.size());
+    }
+    if (!realpath(temp.data(), parentDirectory)) {
+        WTFLogAlways("%s: couldn't retrieve private cache directory path: %d\n", getprogname(), errno);
+        exit(EX_NOPERM);
+    }
+    
+    return parentDirectory;
+}
+
+static inline String sandboxDirectory(ChildProcess::ProcessType processType, const String& parentDirectory)
+{
+    StringBuilder directory;
+    directory.append(parentDirectory);
+    switch (processType) {
+    case ChildProcess::ProcessType::WebContent:
+        directory.append("/com.apple.WebKit.WebContent.Sandbox");
+        break;
+    case ChildProcess::ProcessType::Network:
+        directory.append("/com.apple.WebKit.Networking.Sandbox");
+        break;
+    case ChildProcess::ProcessType::Storage:
+        directory.append("/com.apple.WebKit.Storage.Sandbox");
+        break;
+    case ChildProcess::ProcessType::Plugin:
+        directory.append("/com.apple.WebKit.Plugin.Sandbox");
+        break;
+    }
+
+#if !USE(APPLE_INTERNAL_SDK)
+    // Add .OpenSource suffix so that open source builds don't try to access a data vault used by system Safari.
+    directory.append(".OpenSource");
+#endif
+
+    return directory.toString();
+}
+
+static inline String sandboxFilePath(const String& directoryPath, const CString& header)
+{
+    StringBuilder sandboxFile;
+    sandboxFile.append(directoryPath);
+    sandboxFile.append("/CompiledSandbox+");
+
+    // Make the filename semi-unique based on the contents of the header.
+    auto crypto = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_256);
+    crypto->addBytes(header.data(), header.length());
+    Vector<uint8_t> hash = crypto->computeHash();
+    String readableHash = WTF::base64URLEncode(hash.data(), hash.size());
+
+    sandboxFile.append(readableHash);
+    return sandboxFile.toString();
+}
+
+static bool ensureSandboxCacheDirectory(const SandboxInfo& info)
+{
+    if (!FileSystem::fileIsDirectory(info.parentDirectoryPath, FileSystem::ShouldFollowSymbolicLinks::Yes)) {
+        FileSystem::makeAllDirectories(info.parentDirectoryPath);
+        if (!FileSystem::fileIsDirectory(info.parentDirectoryPath, FileSystem::ShouldFollowSymbolicLinks::Yes)) {
+            WTFLogAlways("%s: Couldn't create sandbox directory\n", getprogname());
+            return false;
+        }
+    }
+
+#if USE(APPLE_INTERNAL_SDK)
+    const char* storageClass = processStorageClass(info.processType);
+    CString directoryPath = FileSystem::fileSystemRepresentation(info.directoryPath);
+    if (directoryPath.isNull())
+        return false;
+
+    auto makeDataVault = [&] {
+        do {
+            if (!rootless_mkdir_datavault(directoryPath.data(), 0700, storageClass))
+                return true;
+        } while (errno == EAGAIN);
+        return false;
+    };
+
+    if (makeDataVault())
+        return true;
+
+    if (errno == EEXIST) {
+        // The directory already exists. First we'll check if it is a data vault. If it is then
+        // we are the ones who created it and we can continue. If it is not a datavault then we'll just
+        // delete it and try to make a new one.
+        if (!rootless_check_datavault_flag(directoryPath.data(), storageClass))
+            return true;
+        
+        bool isDirectory = FileSystem::fileIsDirectory(info.directoryPath, FileSystem::ShouldFollowSymbolicLinks::No);
+        if (isDirectory) {
+            if (!FileSystem::deleteNonEmptyDirectory(info.directoryPath))
+                return false;
+        } else {
+            if (!FileSystem::deleteFile(info.directoryPath))
+                return false;
+        }
+        
+        if (!makeDataVault())
+            return false;
+    } else {
+        WTFLogAlways("Sandbox directory couldn't be created, errno: %d", errno);
+        return false;
+    }
+#else
+    bool hasSandboxDirectory = FileSystem::fileIsDirectory(info.directoryPath, FileSystem::ShouldFollowSymbolicLinks::Yes);
+    if (!hasSandboxDirectory) {
+        if (FileSystem::makeAllDirectories(info.directoryPath)) {
+            ASSERT(FileSystem::fileIsDirectory(info.directoryPath, FileSystem::ShouldFollowSymbolicLinks::Yes));
+            hasSandboxDirectory = true;
+        } else {
+            // We may have raced with someone else making it. That's ok.
+            hasSandboxDirectory = FileSystem::fileIsDirectory(info.directoryPath, FileSystem::ShouldFollowSymbolicLinks::Yes);
+        }
+    }
+
+    if (!hasSandboxDirectory) {
+        // Bailing because we don't have a sandbox directory.
+        return false;
+    }
+#endif // USE(APPLE_INTERNAL_SDK)
+
+    return true;
+}
+    
+static bool writeSandboxDataToCacheFile(const SandboxInfo& info, const Vector<char>& cacheFile)
+{
+    FileHandle file { info.filePath, FileSystem::FileOpenMode::Write, FileSystem::FileLockMode::Exclusive };
+    return file.write(cacheFile.data(), cacheFile.size()) == safeCast<int>(cacheFile.size());
+}
+
+static SandboxProfilePtr compileAndCacheSandboxProfile(const SandboxInfo& info)
+{
+    if (!ensureSandboxCacheDirectory(info))
+        return nullptr;
+
+    char* error = nullptr;
+    CString profilePath = FileSystem::fileSystemRepresentation(info.profilePath);
+    if (profilePath.isNull())
+        return nullptr;
+    SandboxProfilePtr sandboxProfile { sandbox_compile_file(profilePath.data(), info.sandboxParameters.get(), &error) };
+    if (!sandboxProfile) {
+        WTFLogAlways("%s: Couldn't compile WebContent sandbox %s\n", getprogname(), error);
+        return nullptr;
+    }
+    
+    const bool haveBuiltin = sandboxProfile->builtin;
+    int32_t libsandboxVersion = NSVersionOfRunTimeLibrary("sandbox");
+    RELEASE_ASSERT(libsandboxVersion > 0);
+    CachedSandboxHeader cachedHeader {
+        CachedSandboxVersionNumber,
+        static_cast<uint32_t>(libsandboxVersion),
+        safeCast<uint32_t>(info.header.length()),
+        haveBuiltin ? safeCast<uint32_t>(strlen(sandboxProfile->builtin)) : std::numeric_limits<uint32_t>::max(),
+        safeCast<uint32_t>(sandboxProfile->size)
+    };
+    const size_t expectedFileSize = sizeof(cachedHeader) + cachedHeader.headerSize + (haveBuiltin ? cachedHeader.builtinSize : 0) + cachedHeader.dataSize;
+    
+    Vector<char> cacheFile;
+    cacheFile.reserveInitialCapacity(expectedFileSize);
+    cacheFile.append(bitwise_cast<uint8_t*>(&cachedHeader), sizeof(CachedSandboxHeader));
+    cacheFile.append(info.header.data(), info.header.length());
+    if (haveBuiltin)
+        cacheFile.append(sandboxProfile->builtin, cachedHeader.builtinSize);
+    cacheFile.append(sandboxProfile->data, cachedHeader.dataSize);
+
+    if (!writeSandboxDataToCacheFile(info, cacheFile))
+        WTFLogAlways("%s: Unable to cache compiled sandbox", getprogname());
+
+    return sandboxProfile;
+}
+
+static bool tryApplyCachedSandbox(const SandboxInfo& info)
+{
+#if USE(APPLE_INTERNAL_SDK)
+    CString directoryPath = FileSystem::fileSystemRepresentation(info.directoryPath);
+    if (directoryPath.isNull())
+        return false;
+    if (rootless_check_datavault_flag(directoryPath.data(), processStorageClass(info.processType)))
+        return false;
+#endif
+
+    auto contents = fileContents(info.filePath, true, FileSystem::FileLockMode::Shared);
+    if (!contents || contents->isEmpty())
+        return false;
+    Vector<char> cachedSandboxContents = WTFMove(*contents);
+    if (sizeof(CachedSandboxHeader) > cachedSandboxContents.size())
+        return false;
+
+    // This data may be corrupted if the sandbox file was cached on a different platform with different endianness
+    CachedSandboxHeader cachedSandboxHeader;
+    memcpy(&cachedSandboxHeader, cachedSandboxContents.data(), sizeof(CachedSandboxHeader));
+    int32_t libsandboxVersion = NSVersionOfRunTimeLibrary("sandbox");
+    RELEASE_ASSERT(libsandboxVersion > 0);
+    if (static_cast<uint32_t>(libsandboxVersion) != cachedSandboxHeader.libsandboxVersion)
+        return false;
+    if (cachedSandboxHeader.versionNumber != CachedSandboxVersionNumber)
+        return false;
+    const bool haveBuiltin = cachedSandboxHeader.builtinSize != std::numeric_limits<uint32_t>::max();
+
+    // These values are computed based on the disk layout specified below the definition of the CachedSandboxHeader struct
+    // and must be changed if the layout changes.
+    const char* sandboxHeaderPtr = bitwise_cast<char *>(cachedSandboxContents.data()) + sizeof(CachedSandboxHeader);
+    const char* sandboxBuiltinPtr = sandboxHeaderPtr + cachedSandboxHeader.headerSize;
+    unsigned char* sandboxDataPtr = bitwise_cast<unsigned char*>(haveBuiltin ? sandboxBuiltinPtr + cachedSandboxHeader.builtinSize : sandboxBuiltinPtr);
+
+    size_t expectedFileSize = sizeof(CachedSandboxHeader) + cachedSandboxHeader.headerSize + cachedSandboxHeader.dataSize;
+    if (haveBuiltin)
+        expectedFileSize += cachedSandboxHeader.builtinSize;
+    if (cachedSandboxContents.size() != expectedFileSize)
+        return false;
+    if (cachedSandboxHeader.headerSize != info.header.length())
+        return false;
+    if (memcmp(sandboxHeaderPtr, info.header.data(), info.header.length()))
+        return false;
+
+    SandboxProfile profile;
+    CString builtin;
+    profile.builtin = nullptr;
+    profile.size = cachedSandboxHeader.dataSize;
+    if (haveBuiltin) {
+        builtin = CString::newUninitialized(cachedSandboxHeader.builtinSize, profile.builtin);
+        if (builtin.isNull())
+            return false;
+        memcpy(profile.builtin, sandboxBuiltinPtr, cachedSandboxHeader.builtinSize);
+    }
+    ASSERT(static_cast<void *>(sandboxDataPtr + profile.size) <= static_cast<void *>(cachedSandboxContents.data() + cachedSandboxContents.size()));
+    profile.data = sandboxDataPtr;
+
+    if (sandbox_apply(&profile)) {
+        WTFLogAlways("%s: Could not apply cached sandbox\n", getprogname());
+        return false;
+    }
+
+    return true;
+}
+
+static inline const NSBundle *webKit2Bundle()
 {
 #if WK_API_ENABLED
-    NSBundle *webKit2Bundle = [NSBundle bundleForClass:NSClassFromString(@"WKWebView")];
+    const static NSBundle *bundle = [NSBundle bundleForClass:NSClassFromString(@"WKWebView")];
 #else
-    NSBundle *webKit2Bundle = [NSBundle bundleForClass:NSClassFromString(@"WKView")];
+    const static NSBundle *bundle = [NSBundle bundleForClass:NSClassFromString(@"WKView")];
 #endif
-    String defaultProfilePath = [webKit2Bundle pathForResource:[[NSBundle mainBundle] bundleIdentifier] ofType:@"sb"];
 
+    return bundle;
+}
+
+static inline String sandboxProfilePath(const SandboxInitializationParameters& parameters)
+{
+    switch (parameters.mode()) {
+    case SandboxInitializationParameters::ProfileSelectionMode::UseDefaultSandboxProfilePath:
+        return [webKit2Bundle() pathForResource:[[NSBundle mainBundle] bundleIdentifier] ofType:@"sb"];
+    case SandboxInitializationParameters::ProfileSelectionMode::UseOverrideSandboxProfilePath:
+        return parameters.overrideSandboxProfilePath();
+    case SandboxInitializationParameters::ProfileSelectionMode::UseSandboxProfile:
+        return parameters.sandboxProfile();
+    }
+}
+
+static bool compileAndApplySandboxSlowCase(const SandboxInfo& info)
+{
+    char* errorBuf;
+    CString profilePath = FileSystem::fileSystemRepresentation(info.profilePath);
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    if (sandbox_init_with_parameters(profilePath.data(), SANDBOX_NAMED_EXTERNAL, info.initializationParameters.namedParameterArray(), &errorBuf)) {
+#pragma clang diagnostic pop
+        WTFLogAlways("%s: Couldn't initialize sandbox profile [%s], error '%s'\n", getprogname(), profilePath.data(), errorBuf);
+        for (size_t i = 0, count = info.initializationParameters.count(); i != count; ++i)
+            WTFLogAlways("%s=%s\n", info.initializationParameters.name(i), info.initializationParameters.value(i));
+        return false;
+    }
+    return true;
+}
+
+static bool applySandbox(const ChildProcessInitializationParameters& parameters, const SandboxInitializationParameters& sandboxInitializationParameters)
+{
+    String profilePath { sandboxProfilePath(sandboxInitializationParameters) };
+    if (profilePath.isEmpty()) {
+        WTFLogAlways("%s: Profile path is invalid\n", getprogname());
+        return false;
+    }
+
+    SandboxParametersPtr sandboxParameters { sandbox_create_params() };
+    auto header = setAndSerializeSandboxParameters(sandboxInitializationParameters, sandboxParameters, profilePath);
+    if (!header) {
+        WTFLogAlways("%s: Sandbox parameters are invalid\n", getprogname());
+        CRASH();
+    }
+
+    String parentDirectoryPath { sandboxDataVaultParentDirectory() };
+    String directoryPath { sandboxDirectory(parameters.processType, parentDirectoryPath) };
+    String filePath = sandboxFilePath(directoryPath, *header);
+    SandboxInfo info {
+        parentDirectoryPath,
+        directoryPath,
+        filePath,
+        profilePath,
+        sandboxParameters,
+        *header,
+        parameters.processType,
+        sandboxInitializationParameters
+    };
+
+    if (tryApplyCachedSandbox(info))
+        return true;
+
+    SandboxProfilePtr sandboxProfile = compileAndCacheSandboxProfile(info);
+    if (!sandboxProfile)
+        return compileAndApplySandboxSlowCase(info);
+
+    if (sandbox_apply(sandboxProfile.get())) {
+        WTFLogAlways("%s: Couldn't apply compiled sandbox profile, errno: %d\n", getprogname(), errno);
+        exit(EX_NOPERM);
+    }
+
+    return true;
+}
+
+static void initializeSandboxParameters(const ChildProcessInitializationParameters& parameters, SandboxInitializationParameters& sandboxParameters)
+{
+    // Verify user directory suffix.
     if (sandboxParameters.userDirectorySuffix().isNull()) {
         auto userDirectorySuffix = parameters.extraInitializationData.find("user-directory-suffix");
         if (userDirectorySuffix != parameters.extraInitializationData.end())
@@ -153,7 +620,7 @@ void ChildProcess::initializeSandbox(const ChildProcessInitializationParameters&
     }
     setenv("TMPDIR", temporaryDirectory, 1);
 
-    sandboxParameters.addPathParameter("WEBKIT2_FRAMEWORK_DIR", [[webKit2Bundle bundlePath] stringByDeletingLastPathComponent]);
+    sandboxParameters.addPathParameter("WEBKIT2_FRAMEWORK_DIR", [[webKit2Bundle() bundlePath] stringByDeletingLastPathComponent]);
     sandboxParameters.addConfDirectoryParameter("DARWIN_USER_TEMP_DIR", _CS_DARWIN_USER_TEMP_DIR);
     sandboxParameters.addConfDirectoryParameter("DARWIN_USER_CACHE_DIR", _CS_DARWIN_USER_CACHE_DIR);
 
@@ -167,50 +634,22 @@ void ChildProcess::initializeSandbox(const ChildProcessInitializationParameters&
     }
 
     sandboxParameters.addPathParameter("HOME_DIR", pwd.pw_dir);
-
     String path = String::fromUTF8(pwd.pw_dir);
     path.append("/Library");
-
     sandboxParameters.addPathParameter("HOME_LIBRARY_DIR", FileSystem::fileSystemRepresentation(path).data());
-
     path.append("/Preferences");
-
     sandboxParameters.addPathParameter("HOME_LIBRARY_PREFERENCES_DIR", FileSystem::fileSystemRepresentation(path).data());
+}
 
-    switch (sandboxParameters.mode()) {
-    case SandboxInitializationParameters::UseDefaultSandboxProfilePath:
-    case SandboxInitializationParameters::UseOverrideSandboxProfilePath: {
-        String sandboxProfilePath = sandboxParameters.mode() == SandboxInitializationParameters::UseDefaultSandboxProfilePath ? defaultProfilePath : sandboxParameters.overrideSandboxProfilePath();
-        if (!sandboxProfilePath.isEmpty()) {
-            CString profilePath = FileSystem::fileSystemRepresentation(sandboxProfilePath);
-            char* errorBuf;
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-            if (sandbox_init_with_parameters(profilePath.data(), SANDBOX_NAMED_EXTERNAL, sandboxParameters.namedParameterArray(), &errorBuf)) {
-#pragma clang diagnostic pop
-                WTFLogAlways("%s: Couldn't initialize sandbox profile [%s], error '%s'\n", getprogname(), profilePath.data(), errorBuf);
-                for (size_t i = 0, count = sandboxParameters.count(); i != count; ++i)
-                    WTFLogAlways("%s=%s\n", sandboxParameters.name(i), sandboxParameters.value(i));
-                exit(EX_NOPERM);
-            }
-        }
+void ChildProcess::initializeSandbox(const ChildProcessInitializationParameters& parameters, SandboxInitializationParameters& sandboxParameters)
+{
+    TraceScope traceScope(InitializeSandboxStart, InitializeSandboxEnd);
 
-        break;
-    }
-    case SandboxInitializationParameters::UseSandboxProfile: {
-        char* errorBuf;
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-        if (sandbox_init_with_parameters(sandboxParameters.sandboxProfile().utf8().data(), 0, sandboxParameters.namedParameterArray(), &errorBuf)) {
-#pragma clang diagnostic pop
-            WTFLogAlways("%s: Couldn't initialize sandbox profile, error '%s'\n", getprogname(), errorBuf);
-            for (size_t i = 0, count = sandboxParameters.count(); i != count; ++i)
-                WTFLogAlways("%s=%s\n", sandboxParameters.name(i), sandboxParameters.value(i));
-            exit(EX_NOPERM);
-        }
+    initializeSandboxParameters(parameters, sandboxParameters);
 
-        break;
-    }
+    if (!applySandbox(parameters, sandboxParameters)) {
+        WTFLogAlways("%s: Unable to apply sandbox\n", getprogname());
+        CRASH();
     }
 
     if (shouldOverrideQuarantine()) {
index 6cb4c88..634909d 100644 (file)
@@ -29,7 +29,7 @@
 namespace WebKit {
 
 SandboxInitializationParameters::SandboxInitializationParameters()
-    : m_profileSelectionMode(UseDefaultSandboxProfilePath)
+    : m_profileSelectionMode(ProfileSelectionMode::UseDefaultSandboxProfilePath)
 {
 }
 
index 5fef46c..d86614f 100644 (file)
@@ -71,6 +71,8 @@ class StorageProcess : public ChildProcess
     friend NeverDestroyed<StorageProcess>;
 public:
     static StorageProcess& singleton();
+    static constexpr ProcessType processType = ProcessType::Storage;
+
     ~StorageProcess();
 
     WorkQueue& queue() { return m_queue.get(); }
index acd05ff..b132cbf 100644 (file)
                411A8DD920DDB6050060D34F /* WKMockMediaDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKMockMediaDevice.h; sourceTree = "<group>"; };
                411A8DDA20DDB6050060D34F /* WKMockMediaDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKMockMediaDevice.cpp; sourceTree = "<group>"; };
                411B22621E371244004F7363 /* LibWebRTCNetwork.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LibWebRTCNetwork.h; path = Network/webrtc/LibWebRTCNetwork.h; sourceTree = "<group>"; };
+               41303BC920E2F0FD005827BA /* process-plugin-entitlements.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "process-plugin-entitlements.sh"; sourceTree = "<group>"; };
+               41303BCA20E2F248005827BA /* Plugin-OSX-sandbox.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Plugin-OSX-sandbox.entitlements"; sourceTree = "<group>"; };
                413075981DE84FB00039EC69 /* NetworkRTCSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkRTCSocket.cpp; path = NetworkProcess/webrtc/NetworkRTCSocket.cpp; sourceTree = "<group>"; };
                413075991DE84FB00039EC69 /* NetworkRTCSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkRTCSocket.h; path = NetworkProcess/webrtc/NetworkRTCSocket.h; sourceTree = "<group>"; };
                4130759A1DE84FB00039EC69 /* NetworkRTCMonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkRTCMonitor.cpp; path = NetworkProcess/webrtc/NetworkRTCMonitor.cpp; sourceTree = "<group>"; };
                41B7ED70206965900087D853 /* NetworkMDNSRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkMDNSRegister.h; path = NetworkProcess/webrtc/NetworkMDNSRegister.h; sourceTree = "<group>"; };
                41B7ED71206965900087D853 /* NetworkMDNSRegister.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = NetworkMDNSRegister.messages.in; path = NetworkProcess/webrtc/NetworkMDNSRegister.messages.in; sourceTree = "<group>"; };
                41C858191F510DEE0065E085 /* CacheStorageEngineCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheStorageEngineCache.cpp; sourceTree = "<group>"; };
+               41D0FC7820E438DD00076AE8 /* WebContent-OSX-sandbox.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "WebContent-OSX-sandbox.entitlements"; sourceTree = "<group>"; };
+               41D0FC7920E439AD00076AE8 /* process-network-entitlements.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "process-network-entitlements.sh"; sourceTree = "<group>"; };
+               41D0FC7C20E43A5100076AE8 /* Storage-OSX-sandbox.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "Storage-OSX-sandbox.entitlements"; sourceTree = "<group>"; };
+               41D0FC7D20E43A5100076AE8 /* Network-OSX-sandbox.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "Network-OSX-sandbox.entitlements"; sourceTree = "<group>"; };
                41D129D91F3D101400D15E47 /* WebCacheStorageProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebCacheStorageProvider.h; sourceTree = "<group>"; };
                41DC45941E3D6E1E00B11F51 /* NetworkRTCProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkRTCProvider.h; path = NetworkProcess/webrtc/NetworkRTCProvider.h; sourceTree = "<group>"; };
                41DC45951E3D6E1E00B11F51 /* NetworkRTCProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkRTCProvider.cpp; path = NetworkProcess/webrtc/NetworkRTCProvider.cpp; sourceTree = "<group>"; };
                                1A4F976C100E7B6600637A18 /* FeatureDefines.xcconfig */,
                                37119A7D20CCB64E002C6DC9 /* Network-iOS-minimalsimulator.entitlements */,
                                7C0BB9A918DCDF5A0006C086 /* Network-iOS.entitlements */,
+                               41D0FC7D20E43A5100076AE8 /* Network-OSX-sandbox.entitlements */,
                                BC8283AB16B4BEAD00A278FE /* NetworkService.xcconfig */,
+                               41303BCA20E2F248005827BA /* Plugin-OSX-sandbox.entitlements */,
                                A1EDD2DB1884B96400BBFE98 /* PluginProcessShim.xcconfig */,
                                BC8283F216B4FC5300A278FE /* PluginService.32.xcconfig */,
                                BC8283F416B4FC5300A278FE /* PluginService.64.xcconfig */,
                                37E83D401B37D27B002079EE /* SandboxProfiles.xcconfig */,
                                A1EDD2DC1884B9B500BBFE98 /* SecItemShim.xcconfig */,
                                5183B3931379F85C00E8754E /* Shim.xcconfig */,
+                               41D0FC7C20E43A5100076AE8 /* Storage-OSX-sandbox.entitlements */,
                                51A60B29180CCD9000F3BF50 /* StorageService.xcconfig */,
                                1A4F976E100E7B6600637A18 /* Version.xcconfig */,
                                37119A7E20CCB64E002C6DC9 /* WebContent-iOS-minimalsimulator.entitlements */,
                                7C0BB9A818DCDE890006C086 /* WebContent-iOS.entitlements */,
                                37B418EB1C9624F20031E63B /* WebContent-OSX-restricted.entitlements */,
+                               41D0FC7820E438DD00076AE8 /* WebContent-OSX-sandbox.entitlements */,
                                7AF66E1120C07CB6007828EA /* WebContent-OSX.entitlements */,
                                372EBB4A2017E76000085064 /* WebContentService.Development.xcconfig */,
                                BCACC40E16B0B8A800B6E092 /* WebContentService.xcconfig */,
                                0FC0856F187CE0A900780D86 /* messages.py */,
                                0FC08570187CE0A900780D86 /* model.py */,
                                0FC08571187CE0A900780D86 /* parser.py */,
+                               41D0FC7920E439AD00076AE8 /* process-network-entitlements.sh */,
+                               41303BC920E2F0FD005827BA /* process-plugin-entitlements.sh */,
                                7ACFAAD820B88D4F00C53203 /* process-webcontent-entitlements.sh */,
                        );
                        path = Scripts;
                        isa = PBXNativeTarget;
                        buildConfigurationList = BC8283BD16B4BF7700A278FE /* Build configuration list for PBXNativeTarget "Networking" */;
                        buildPhases = (
+                               41D0FC7F20E43B0B00076AE8 /* Remove stale entitlements file */,
                                BC8283AD16B4BF7700A278FE /* Sources */,
                                BC8283AE16B4BF7700A278FE /* Frameworks */,
                                BC8283AF16B4BF7700A278FE /* Resources */,
+                               41D0FC8020E43B4500076AE8 /* Unlock keychain */,
+                               41D0FC8120E43B7000076AE8 /* Process Network entitlements */,
                        );
                        buildRules = (
                        );
                        isa = PBXNativeTarget;
                        buildConfigurationList = BC82840416B4FDDE00A278FE /* Build configuration list for PBXNativeTarget "Plugin.32" */;
                        buildPhases = (
+                               41303BC320E2EC67005827BA /* Remove stale entitlement file */,
                                BC8283F516B4FDDE00A278FE /* Sources */,
                                BC8283F616B4FDDE00A278FE /* Frameworks */,
                                BC8283F716B4FDDE00A278FE /* Resources */,
+                               41303BC420E2ED41005827BA /* Unlock keychain */,
+                               41303BC520E2ED54005827BA /* Process Plugin entitlements */,
                        );
                        buildRules = (
                        );
                        isa = PBXNativeTarget;
                        buildConfigurationList = BC82842A16B4FDF700A278FE /* Build configuration list for PBXNativeTarget "Plugin.64" */;
                        buildPhases = (
+                               41303BC620E2EFDF005827BA /* Remove stale entitlement file */,
                                BC82841B16B4FDF600A278FE /* Sources */,
                                BC82841C16B4FDF600A278FE /* Frameworks */,
                                BC82841D16B4FDF600A278FE /* Resources */,
+                               41303BC720E2F016005827BA /* Unlock keychain */,
+                               41303BC820E2F047005827BA /* Process Plugin entitlements */,
                        );
                        buildRules = (
                        );
                        name = "Copy Additional Resources";
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "set -e\n\nRELATIVE_SOURCE_PATH=\"usr/local/include/WebKitAdditions/WebKit/AdditionalResources\"\nSOURCE_PATH=\"$BUILT_PRODUCTS_DIR/$RELATIVE_SOURCE_PATH\"\n\nif [[ ! -d \"$SOURCE_PATH\" ]]; then\n    SOURCE_PATH=\"$SDK_DIR/$RELATIVE_SOURCE_PATH\"\nfi\n\nif [[ -d \"$SOURCE_PATH\" ]]; then\n    ditto $SOURCE_PATH \"$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH\"\nfi";
+                       shellScript = "set -e\n\nRELATIVE_SOURCE_PATH=\"usr/local/include/WebKitAdditions/WebKit/AdditionalResources\"\nSOURCE_PATH=\"$BUILT_PRODUCTS_DIR/$RELATIVE_SOURCE_PATH\"\n\nif [[ ! -d \"$SOURCE_PATH\" ]]; then\n    SOURCE_PATH=\"$SDK_DIR/$RELATIVE_SOURCE_PATH\"\nfi\n\nif [[ -d \"$SOURCE_PATH\" ]]; then\n    ditto $SOURCE_PATH \"$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH\"\nfi\n";
                };
                3713F0231429063D0036387F /* Check For Inappropriate Objective-C Class Names */ = {
                        isa = PBXShellScriptBuildPhase;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "if [[ \"${WK_MANUAL_SANDBOXING_ENABLED}\" != \"YES\" || \"${WK_PLATFORM_NAME}\" == \"macosx\" ]]; then\n    exit\nfi\n\nif [[ \"${ACTION}\" == \"build\" || \"${ACTION}\" == \"install\" ]]; then\n    for ((i = 0; i < ${SCRIPT_INPUT_FILE_COUNT}; ++i)); do\n        eval ENTITLEMENTS=\\${SCRIPT_INPUT_FILE_${i}}\n        ENTITLEMENTS_BASE=${ENTITLEMENTS##*/}\n        ENTITLEMENTS_BASE=${ENTITLEMENTS_BASE%.entitlements}\n        plutil -remove seatbelt-profiles -o \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebKit2/${ENTITLEMENTS_BASE}-no-sandbox.entitlements\" \"${ENTITLEMENTS}\"\n    done\nfi";
+                       shellScript = "if [[ \"${WK_MANUAL_SANDBOXING_ENABLED}\" != \"YES\" || \"${WK_PLATFORM_NAME}\" == \"macosx\" ]]; then\n    exit\nfi\n\nif [[ \"${ACTION}\" == \"build\" || \"${ACTION}\" == \"install\" ]]; then\n    for ((i = 0; i < ${SCRIPT_INPUT_FILE_COUNT}; ++i)); do\n        eval ENTITLEMENTS=\\${SCRIPT_INPUT_FILE_${i}}\n        ENTITLEMENTS_BASE=${ENTITLEMENTS##*/}\n        ENTITLEMENTS_BASE=${ENTITLEMENTS_BASE%.entitlements}\n        plutil -remove seatbelt-profiles -o \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebKit2/${ENTITLEMENTS_BASE}-no-sandbox.entitlements\" \"${ENTITLEMENTS}\"\n    done\nfi\n";
                };
                375A248817E5048E00C9A086 /* Postprocess WKBase.h */ = {
                        isa = PBXShellScriptBuildPhase;
                        shellPath = /bin/sh;
                        shellScript = "if [[ \"${WK_MANUAL_SANDBOXING_ENABLED}\" != \"YES\" || \"${WK_PLATFORM_NAME}\" == \"macosx\" || \"${WK_PLATFORM_NAME}\" == \"iosmac\" ]]; then\n    exit\nfi\n\nif [[ \"${ACTION}\" == \"build\" || \"${ACTION}\" == \"install\" ]]; then\n    for ((i = 0; i < ${SCRIPT_INPUT_FILE_COUNT}; ++i)); do\n        eval SANDBOX_PROFILE=\\${SCRIPT_INPUT_FILE_${i}}\n        ditto \"${SANDBOX_PROFILE}\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/${SANDBOX_PROFILE##*/}\"\n    done\nfi\n";
                };
+               41303BC320E2EC67005827BA /* Remove stale entitlement file */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputFileListPaths = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Remove stale entitlement file";
+                       outputFileListPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "# We autogenerate this file, so don't want to retain an old copy during builds.\nrm -f ${TEMP_FILE_DIR}/${FULL_PRODUCT_NAME}.xcent\n";
+               };
+               41303BC420E2ED41005827BA /* Unlock keychain */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputFileListPaths = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Unlock keychain";
+                       outputFileListPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "UNLOCK_SCRIPT_PATH=\"${SRCROOT}/../../../Internal/Tools/Scripts/unlock-safari-engineering-keychain-if-needed\"\n\n[[ -x \"${UNLOCK_SCRIPT_PATH}\" ]] && exec \"${UNLOCK_SCRIPT_PATH}\"\n\nexit 0\n";
+               };
+               41303BC520E2ED54005827BA /* Process Plugin entitlements */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputFileListPaths = (
+                       );
+                       inputPaths = (
+                               "$(TEMP_FILE_DIR)/$(FULL_PRODUCT_NAME).xcent",
+                       );
+                       name = "Process Plugin entitlements";
+                       outputFileListPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "Scripts/process-plugin-entitlements.sh\n";
+               };
+               41303BC620E2EFDF005827BA /* Remove stale entitlement file */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputFileListPaths = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Remove stale entitlement file";
+                       outputFileListPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "# We autogenerate this file, so don't want to retain an old copy during builds.\nrm -f ${TEMP_FILE_DIR}/${FULL_PRODUCT_NAME}.xcent\n";
+               };
+               41303BC720E2F016005827BA /* Unlock keychain */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputFileListPaths = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Unlock keychain";
+                       outputFileListPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "UNLOCK_SCRIPT_PATH=\"${SRCROOT}/../../../Internal/Tools/Scripts/unlock-safari-engineering-keychain-if-needed\"\n\n[[ -x \"${UNLOCK_SCRIPT_PATH}\" ]] && exec \"${UNLOCK_SCRIPT_PATH}\"\n\nexit 0\n";
+               };
+               41303BC820E2F047005827BA /* Process Plugin entitlements */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputFileListPaths = (
+                       );
+                       inputPaths = (
+                               "$(TEMP_FILE_DIR)/$(FULL_PRODUCT_NAME).xcent",
+                       );
+                       name = "Process Plugin entitlements";
+                       outputFileListPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "Scripts/process-plugin-entitlements.sh\n";
+               };
+               41D0FC7F20E43B0B00076AE8 /* Remove stale entitlements file */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputFileListPaths = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Remove stale entitlements file";
+                       outputFileListPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "# We autogenerate this file, so don't want to retain an old copy during builds.\nrm -f ${TEMP_FILE_DIR}/${FULL_PRODUCT_NAME}.xcent\n";
+               };
+               41D0FC8020E43B4500076AE8 /* Unlock keychain */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputFileListPaths = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Unlock keychain";
+                       outputFileListPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "UNLOCK_SCRIPT_PATH=\"${SRCROOT}/../../../Internal/Tools/Scripts/unlock-safari-engineering-keychain-if-needed\"\n\n[[ -x \"${UNLOCK_SCRIPT_PATH}\" ]] && exec \"${UNLOCK_SCRIPT_PATH}\"\n\nexit 0\n";
+               };
+               41D0FC8120E43B7000076AE8 /* Process Network entitlements */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputFileListPaths = (
+                       );
+                       inputPaths = (
+                               "$(TEMP_FILE_DIR)/$(FULL_PRODUCT_NAME).xcent",
+                       );
+                       name = "Process Network entitlements";
+                       outputFileListPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "Scripts/process-network-entitlements.sh\n";
+               };
                5DF408C5131DD46700130071 /* Check For Weak VTables and Externals */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
index 1159f84..030a718 100644 (file)
@@ -109,6 +109,7 @@ struct WebsiteDataStoreParameters;
 class WebProcess : public ChildProcess {
 public:
     static WebProcess& singleton();
+    static constexpr ProcessType processType = ProcessType::WebContent;
 
     template <typename T>
     T* supplement()
index 5a05225..7f61eb1 100644 (file)
@@ -1,3 +1,14 @@
+2018-07-23  Ben Richards  <benton_richards@apple.com>
+
+        We should cache the compiled sandbox profile in a data vault
+        https://bugs.webkit.org/show_bug.cgi?id=184991
+
+        Reviewed by Ryosuke Niwa.
+
+        Added trace points for sandbox initialization
+
+        * Tracing/SystemTracePoints.plist:
+
 2018-07-23  Zalan Bujtas  <zalan@apple.com>
 
         DRT relies on [webView display] to call -viewWillDraw on the WebHTMLView
index e9e1776..0e1a678 100644 (file)
                  <key>CodeEnd</key>
                  <string>14004</string>
              </dict>
+             <dict>
+                 <key>Name</key>
+                 <string>Initialize Sandbox</string>
+                 <key>Type</key>
+                 <string>Interval</string>
+                 <key>Component</key>
+                 <string>47</string>
+                 <key>CodeBegin</key>
+                 <string>14005</string>
+                 <key>CodeEnd</key>
+                 <string>14006</string>
+             </dict>
          </array>
      </dict>
  </array>