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

Patch by Ben Richards <benton_richards@apple.com> on 2018-08-15
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 and WebContent 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/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-sandbox-entitlements.sh: Added.
* Scripts/process-webcontent-sandbox-entitlements.sh: Added.
* 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::sandboxDataVaultParentDirectory):
(WebKit::sandboxDirectory):
(WebKit::sandboxFilePath):
(WebKit::ensureSandboxCacheDirectory):
(WebKit::writeSandboxDataToCacheFile):
(WebKit::compileAndCacheSandboxProfile):
(WebKit::tryApplyCachedSandbox):
(WebKit::webKit2Bundle):
(WebKit::getSandboxProfileOrProfilePath):
(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@234910 268f45cc-cd09-0410-ab3c-d52691b4dbfc

28 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/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-sandbox-entitlements.sh [new file with mode: 0755]
Source/WebKit/Scripts/process-webcontent-sandbox-entitlements.sh [new file with mode: 0755]
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 ba62c47..7b9ba0f 100644 (file)
@@ -1,3 +1,15 @@
+2018-08-15  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-08-15  Michael Catanzaro  <mcatanzaro@igalia.com>
 
         [WPE][GTK] WaylandCompositor fails to properly remove surface from its page map
index b52be8d..105196e 100644 (file)
@@ -96,6 +96,8 @@ enum TracePointCode {
     CommitLayerTreeEnd,
     ProcessLaunchStart,
     ProcessLaunchEnd,
+    InitializeSandboxStart,
+    InitializeSandboxEnd,
 };
 
 #ifdef __cplusplus
index fa18c9e..b2681b4 100644 (file)
@@ -42,6 +42,21 @@ enum sandbox_filter_type {
 
 WTF_EXTERN_C_BEGIN
 
+typedef struct {
+    char* builtin;
+    unsigned char* data;
+    size_t size;
+#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101300
+    char* trace;
+#endif
+} *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 +69,13 @@ 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);
+sandbox_profile_t sandbox_compile_string(const char *data, sandbox_params_t, char **error);
+void sandbox_free_profile(sandbox_profile_t);
+int sandbox_apply(sandbox_profile_t);
 
 WTF_EXTERN_C_END
 
index f0bde7d..dcfe29f 100644 (file)
@@ -1,3 +1,22 @@
+2018-08-15  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-08-15  Ryosuke Niwa  <rniwa@webkit.org>
 
         Can't share an app on AppStore to WeChat due to a release assert
index 1c3f532..ee4f361 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_lockMode { lockMode }
+    , m_shouldLock { true }
 {
 }
 
@@ -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..d118308 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 };
+    OptionSet<FileSystem::FileLockMode> m_lockMode;
+    bool m_shouldLock { false };
 };
 
 } // 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..d38b0c8 100644 (file)
@@ -134,5 +134,10 @@ 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 a1c1fac..6597f45 100644 (file)
@@ -1,3 +1,68 @@
+2018-08-15  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 and WebContent 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/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-sandbox-entitlements.sh: Added.
+        * Scripts/process-webcontent-sandbox-entitlements.sh: Added.
+        * 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::sandboxDataVaultParentDirectory):
+        (WebKit::sandboxDirectory):
+        (WebKit::sandboxFilePath):
+        (WebKit::ensureSandboxCacheDirectory):
+        (WebKit::writeSandboxDataToCacheFile):
+        (WebKit::compileAndCacheSandboxProfile):
+        (WebKit::tryApplyCachedSandbox):
+        (WebKit::webKit2Bundle):
+        (WebKit::getSandboxProfileOrProfilePath):
+        (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-08-15  Ross Kirsling  <ross.kirsling@sony.com>
 
         [WinCairo] Unreviewed build fix after r234896.
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/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 7c33e75..1914898 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-sandbox-entitlements.sh b/Source/WebKit/Scripts/process-network-sandbox-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-webcontent-sandbox-entitlements.sh b/Source/WebKit/Scripts/process-webcontent-sandbox-entitlements.sh
new file mode 100755 (executable)
index 0000000..1b84f2f
--- /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 WebContent process.";
+        /usr/libexec/PlistBuddy -c "Merge Configurations/WebContent-OSX-sandbox.entitlements" "${PROCESSED_XCENT_FILE}";
+    fi
+fi
index 95a3104..c919091 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
@@ -150,6 +147,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 6a3ac61..f7ccbe2 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 88636a8..bdcb2a9 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
+
+#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+#define USE_CACHE_COMPILED_SANDBOX 1
+#else
+#define USE_CACHE_COMPILED_SANDBOX 0
 #endif
 
 typedef bool (^LSServerConnectionAllowedBlock) ( CFDictionaryRef optionsRef );
@@ -57,6 +75,68 @@ using namespace WebCore;
 
 namespace WebKit {
 
+#if USE(CACHE_COMPILED_SANDBOX)
+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 SandboxParametersPtr& sandboxParameters, const CString& header, const ChildProcess::ProcessType& processType, const SandboxInitializationParameters& initializationParameters, const String& profileOrProfilePath, bool isProfilePath)
+        : parentDirectoryPath { parentDirectoryPath }
+        , directoryPath { directoryPath }
+        , filePath { filePath }
+        , sandboxParameters { sandboxParameters }
+        , header { header }
+        , processType { processType }
+        , initializationParameters { initializationParameters }
+        , profileOrProfilePath { profileOrProfilePath }
+        , isProfilePath { isProfilePath }
+    {
+    }
+
+    const String& parentDirectoryPath;
+    const String& directoryPath;
+    const String& filePath;
+    const SandboxParametersPtr& sandboxParameters;
+    const CString& header;
+    const ChildProcess::ProcessType& processType;
+    const SandboxInitializationParameters& initializationParameters;
+    const String& profileOrProfilePath;
+    const bool isProfilePath;
+};
+
+constexpr uint32_t CachedSandboxVersionNumber = 0;
+#endif // USE(CACHE_COMPILED_SANDBOX)
+
 static void initializeTimerCoalescingPolicy()
 {
     // Set task_latency and task_throughput QOS tiers as appropriate for a visible application.
@@ -112,15 +192,424 @@ static OSStatus enableSandboxStyleFileQuarantine()
 #endif
 }
 
-void ChildProcess::initializeSandbox(const ChildProcessInitializationParameters& parameters, SandboxInitializationParameters& sandboxParameters)
+#if USE(CACHE_COMPILED_SANDBOX)
+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 // USE(APPLE_INTERNAL_SDK)
+
+static std::optional<CString> setAndSerializeSandboxParameters(const SandboxInitializationParameters& initializationParameters, const SandboxParametersPtr& sandboxParameters, const String& profileOrProfilePath, bool isProfilePath)
+{
+    StringBuilder builder;
+    for (size_t i = 0; i < initializationParameters.count(); ++i) {
+        const char* name = initializationParameters.name(i);
+        const char* value = initializationParameters.value(i);
+        if (sandbox_set_param(sandboxParameters.get(), name, value)) {
+            WTFLogAlways("%s: Could not set sandbox parameter: %s\n", getprogname(), strerror(errno));
+            CRASH();
+        }
+        builder.append(name, strlen(name));
+        builder.append(':');
+        builder.append(value, strlen(value));
+        builder.append(':');
+    }
+    if (isProfilePath) {
+        auto contents = fileContents(profileOrProfilePath);
+        if (!contents)
+            return std::nullopt;
+        builder.append(contents->data(), contents->size());
+    } else
+        builder.append(profileOrProfilePath);
+    return builder.toString().ascii();
+}
+
+static String sandboxDataVaultParentDirectory()
+{
+    char temp[PATH_MAX];
+    size_t length = confstr(_CS_DARWIN_USER_CACHE_DIR, temp, sizeof(temp));
+    if (!length) {
+        WTFLogAlways("%s: Could not retrieve user cache directory path: %s\n", getprogname(), strerror(errno));
+        exit(EX_NOPERM);
+    }
+    RELEASE_ASSERT(length <= sizeof(temp));
+    char resolvedPath[PATH_MAX];
+    if (!realpath(temp, resolvedPath)) {
+        WTFLogAlways("%s: Could not canonicalize user cache directory path: %s\n", getprogname(), strerror(errno));
+        exit(EX_NOPERM);
+    }
+    return resolvedPath;
+}
+
+static 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 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: Could not 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("%s: Sandbox directory couldn't be created: ", getprogname(), strerror(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 profileOrProfilePath = info.isProfilePath ? FileSystem::fileSystemRepresentation(info.profileOrProfilePath) : info.profileOrProfilePath.utf8();
+    if (profileOrProfilePath.isNull())
+        return nullptr;
+    SandboxProfilePtr sandboxProfile { info.isProfilePath ? sandbox_compile_file(profileOrProfilePath.data(), info.sandboxParameters.get(), &error) : sandbox_compile_string(profileOrProfilePath.data(), info.sandboxParameters.get(), &error) };
+    if (!sandboxProfile) {
+        WTFLogAlways("%s: Could not 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\n", 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: %s\n", getprogname(), strerror(errno));
+        return false;
+    }
+
+    return true;
+}
+#endif // USE(CACHE_COMPILED_SANDBOX)
+
+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 void getSandboxProfileOrProfilePath(const SandboxInitializationParameters& parameters, String& profileOrProfilePath, bool& isProfilePath)
+{
+    switch (parameters.mode()) {
+    case SandboxInitializationParameters::ProfileSelectionMode::UseDefaultSandboxProfilePath:
+        profileOrProfilePath = [webKit2Bundle() pathForResource:[[NSBundle mainBundle] bundleIdentifier] ofType:@"sb"];
+        isProfilePath = true;
+        return;
+    case SandboxInitializationParameters::ProfileSelectionMode::UseOverrideSandboxProfilePath:
+        profileOrProfilePath = parameters.overrideSandboxProfilePath();
+        isProfilePath = true;
+        return;
+    case SandboxInitializationParameters::ProfileSelectionMode::UseSandboxProfile:
+        profileOrProfilePath = parameters.sandboxProfile();
+        isProfilePath = false;
+        return;
+    }
+}
+
+static bool compileAndApplySandboxSlowCase(const String& profileOrProfilePath, bool isProfilePath, const SandboxInitializationParameters& parameters)
+{
+    char* errorBuf;
+    CString temp = isProfilePath ? FileSystem::fileSystemRepresentation(profileOrProfilePath) : profileOrProfilePath.utf8();
+    uint64_t flags = isProfilePath ? SANDBOX_NAMED_EXTERNAL : 0;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    if (sandbox_init_with_parameters(temp.data(), flags, parameters.namedParameterArray(), &errorBuf)) {
+#pragma clang diagnostic pop
+        WTFLogAlways("%s: Could not initialize sandbox profile [%s], error '%s'\n", getprogname(), temp.data(), errorBuf);
+        for (size_t i = 0, count = parameters.count(); i != count; ++i)
+            WTFLogAlways("%s=%s\n", parameters.name(i), parameters.value(i));
+        return false;
+    }
+    return true;
+}
+
+static bool applySandbox(const ChildProcessInitializationParameters& parameters, const SandboxInitializationParameters& sandboxInitializationParameters, const String& dataVaultParentDirectory)
+{
+    String profileOrProfilePath;
+    bool isProfilePath;
+    getSandboxProfileOrProfilePath(sandboxInitializationParameters, profileOrProfilePath, isProfilePath);
+    if (profileOrProfilePath.isEmpty()) {
+        WTFLogAlways("%s: Profile path is invalid\n", getprogname());
+        CRASH();
+    }
+
+#if USE(CACHE_COMPILED_SANDBOX)
+    // The plugin process's DARWIN_USER_TEMP_DIR and DARWIN_USER_CACHE_DIR sandbox parameters are randomized so
+    // so the compiled sandbox should not be cached because it won't be reused.
+    if (parameters.processType == ChildProcess::ProcessType::Plugin)
+        return compileAndApplySandboxSlowCase(profileOrProfilePath, isProfilePath, sandboxInitializationParameters);
+
+    SandboxParametersPtr sandboxParameters { sandbox_create_params() };
+    if (!sandboxParameters) {
+        WTFLogAlways("%s: Could not create sandbox parameters\n", getprogname());
+        CRASH();
+    }
+    auto header = setAndSerializeSandboxParameters(sandboxInitializationParameters, sandboxParameters, profileOrProfilePath, isProfilePath);
+    if (!header) {
+        WTFLogAlways("%s: Sandbox parameters are invalid\n", getprogname());
+        CRASH();
+    }
+
+    String directoryPath { sandboxDirectory(parameters.processType, dataVaultParentDirectory) };
+    String filePath = sandboxFilePath(directoryPath, *header);
+    SandboxInfo info {
+        dataVaultParentDirectory,
+        directoryPath,
+        filePath,
+        sandboxParameters,
+        *header,
+        parameters.processType,
+        sandboxInitializationParameters,
+        profileOrProfilePath,
+        isProfilePath
+    };
+
+    if (tryApplyCachedSandbox(info))
+        return true;
+
+    SandboxProfilePtr sandboxProfile = compileAndCacheSandboxProfile(info);
+    if (!sandboxProfile)
+        return compileAndApplySandboxSlowCase(profileOrProfilePath, isProfilePath, sandboxInitializationParameters);
+
+    if (sandbox_apply(sandboxProfile.get())) {
+        WTFLogAlways("%s: Could not apply compiled sandbox: %s\n", getprogname(), strerror(errno));
+        CRASH();
+    }
+
+    return true;
+#else
+    UNUSED_PARAM(parameters);
+    UNUSED_PARAM(dataVaultParentDirectory);
+    return compileAndApplySandboxSlowCase(profileOrProfilePath, isProfilePath, sandboxInitializationParameters);
+#endif // USE(CACHE_COMPILED_SANDBOX)
+}
+
+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())
@@ -152,7 +641,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);
 
@@ -166,50 +655,30 @@ 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);
-        }
+#if USE(CACHE_COMPILED_SANDBOX)
+    // This must be called before initializeSandboxParameters so that the path does not include the user directory suffix.
+    // We don't want the user directory suffix because we want all processes of the same type to use the same cache directory.
+    String dataVaultParentDirectory { sandboxDataVaultParentDirectory() };
+#else
+    String dataVaultParentDirectory;
+#endif
 
-        break;
-    }
+    initializeSandboxParameters(parameters, sandboxParameters);
+
+    if (!applySandbox(parameters, sandboxParameters, dataVaultParentDirectory)) {
+        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 c833c1f..865ada9 100644 (file)
                414DEDD61F9EDDE00047C40D /* ServiceWorkerProcessProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerProcessProxy.cpp; sourceTree = "<group>"; };
                4151E5C31FBB90A900E47E2D /* FormDataReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormDataReference.h; sourceTree = "<group>"; };
                4157E4AF20E2EC9800A6C0D7 /* com.google.o1dbrowserplugin.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = com.google.o1dbrowserplugin.sb; sourceTree = "<group>"; };
+               4188C154211377700012ABCD /* process-network-sandbox-entitlements.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "process-network-sandbox-entitlements.sh"; sourceTree = "<group>"; };
+               4188C156211377E80012ABCD /* process-webcontent-sandbox-entitlements.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "process-webcontent-sandbox-entitlements.sh"; sourceTree = "<group>"; };
+               4188C157211378520012ABCD /* Storage-OSX-sandbox.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "Storage-OSX-sandbox.entitlements"; sourceTree = "<group>"; };
+               4188C158211378520012ABCD /* WebContent-OSX-sandbox.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "WebContent-OSX-sandbox.entitlements"; sourceTree = "<group>"; };
                41897ECB1F415D5C0016FA42 /* WebCacheStorageConnection.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = WebCacheStorageConnection.messages.in; sourceTree = "<group>"; };
                41897ECC1F415D5C0016FA42 /* WebCacheStorageProvider.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebCacheStorageProvider.cpp; sourceTree = "<group>"; };
                41897ECD1F415D5C0016FA42 /* WebCacheStorageConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebCacheStorageConnection.h; 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>"; };
+               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 */,
                                A1EDD2DB1884B96400BBFE98 /* PluginProcessShim.xcconfig */,
                                BC8283F216B4FC5300A278FE /* PluginService.32.xcconfig */,
                                37E83D401B37D27B002079EE /* SandboxProfiles.xcconfig */,
                                A1EDD2DC1884B9B500BBFE98 /* SecItemShim.xcconfig */,
                                5183B3931379F85C00E8754E /* Shim.xcconfig */,
+                               4188C157211378520012ABCD /* Storage-OSX-sandbox.entitlements */,
                                51A60B29180CCD9000F3BF50 /* StorageService.xcconfig */,
                                1A4F976E100E7B6600637A18 /* Version.xcconfig */,
                                37119A7E20CCB64E002C6DC9 /* WebContent-iOS-minimalsimulator.entitlements */,
                                7C0BB9A818DCDE890006C086 /* WebContent-iOS.entitlements */,
                                37B418EB1C9624F20031E63B /* WebContent-or-Plugin-OSX-restricted.entitlements */,
+                               4188C158211378520012ABCD /* WebContent-OSX-sandbox.entitlements */,
                                7AF66E1120C07CB6007828EA /* WebContent-OSX.entitlements */,
                                372EBB4A2017E76000085064 /* WebContentService.Development.xcconfig */,
                                BCACC40E16B0B8A800B6E092 /* WebContentService.xcconfig */,
                                0FC0856F187CE0A900780D86 /* messages.py */,
                                0FC08570187CE0A900780D86 /* model.py */,
                                0FC08571187CE0A900780D86 /* parser.py */,
+                               4188C154211377700012ABCD /* process-network-sandbox-entitlements.sh */,
                                7ACFAAD820B88D4F00C53203 /* process-webcontent-or-plugin-entitlements.sh */,
+                               4188C156211377E80012ABCD /* process-webcontent-sandbox-entitlements.sh */,
                        );
                        path = Scripts;
                        sourceTree = "<group>";
                        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 = (
                        );
                        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";
                };
+               41D0FC7F20E43B0B00076AE8 /* Remove stale entitlements file */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Remove stale entitlements file";
+                       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 = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Unlock keychain";
+                       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 = (
+                       );
+                       inputPaths = (
+                               "$(TEMP_FILE_DIR)/$(FULL_PRODUCT_NAME).xcent",
+                       );
+                       name = "Process Network entitlements";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "Scripts/process-network-sandbox-entitlements.sh\n";
+               };
                5DF408C5131DD46700130071 /* Check For Weak VTables and Externals */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        buildActionMask = 2147483647;
                        files = (
                        );
-                       inputFileListPaths = (
-                       );
                        inputPaths = (
                                "$(TEMP_FILE_DIR)/$(FULL_PRODUCT_NAME).xcent",
                        );
                        name = "Process Plugin entitlements";
-                       outputFileListPaths = (
-                       );
                        outputPaths = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        buildActionMask = 2147483647;
                        files = (
                        );
-                       inputFileListPaths = (
-                       );
                        inputPaths = (
                                "$(TEMP_FILE_DIR)/$(FULL_PRODUCT_NAME).xcent",
                        );
                        name = "Process Plugin entitlements";
-                       outputFileListPaths = (
-                       );
                        outputPaths = (
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "Scripts/process-webcontent-or-plugin-entitlements.sh\n";
+                       shellScript = "Scripts/process-webcontent-or-plugin-entitlements.sh\nScripts/process-webcontent-sandbox-entitlements.sh\n";
                };
                7AFCBD5520B8917D00F55C9C /* Process WebContent entitlements */ = {
                        isa = PBXShellScriptBuildPhase;
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "Scripts/process-webcontent-or-plugin-entitlements.sh\n";
+                       shellScript = "Scripts/process-webcontent-or-plugin-entitlements.sh\nScripts/process-webcontent-sandbox-entitlements.sh\n";
                };
                99CA3862207286DB00BAD578 /* Copy WebDriver Atoms to Framework Private Headers */ = {
                        isa = PBXShellScriptBuildPhase;
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 3e7cc4e..69d3158 100644 (file)
@@ -1,3 +1,14 @@
+2018-08-15  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-08-15  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unreviewed, rolling out r234870.
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>