[Mac] Use the PID of the WebContent process when issuing local file read sandbox extensions
https://bugs.webkit.org/show_bug.cgi?id=200543
Source/WebKit:

Reviewed by Brent Fulgham.

Adopt SPI to issue a process-specific sandbox extension for local file read, passing it the process
identifier of the WebContent process.

* Shared/Cocoa/SandboxExtensionCocoa.mm:
(WebKit::SandboxExtensionImpl::sandboxExtensionForType):
(WebKit::SandboxExtension::createHandleForReadByPid):
* Shared/SandboxExtension.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::maybeInitializeSandboxExtensionHandle):

Source/WTF:

<rdar://problem/49394015>

Reviewed by Brent Fulgham.

Add new SPI.

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


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@248440 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog
index 6e295d2..737647f 100644
--- a/Source/WTF/ChangeLog
+++ b/Source/WTF/ChangeLog
@@ -1,3 +1,16 @@
+2019-08-08  Per Arne Vollan  <pvollan@apple.com>
+
+        [Mac] Use the PID of the WebContent process when issuing local file read sandbox extensions
+        https://bugs.webkit.org/show_bug.cgi?id=200543
+        <rdar://problem/49394015>
+
+        Reviewed by Brent Fulgham.
+
+        Add new SPI.
+
+        * wtf/Platform.h:
+        * wtf/spi/darwin/SandboxSPI.h:
+
 2019-08-07  Chris Dumez  <cdumez@apple.com>
 
         Tighten WeakPtr threading assertions for GC threads
diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h
index 406a514..84d49fd 100644
--- a/Source/WTF/wtf/Platform.h
+++ b/Source/WTF/wtf/Platform.h
@@ -1530,6 +1530,10 @@
 #define HAVE_SANDBOX_ISSUE_MACH_EXTENSION_TO_PROCESS_BY_PID 1
 #endif
 
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400) || (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 130000)
+#define HAVE_SANDBOX_ISSUE_READ_EXTENSION_TO_PROCESS_BY_PID 1
+#endif
+
 #if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500) || (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 130000)
 #define HAVE_MDNS_FAST_REGISTRATION 1
 #endif
diff --git a/Source/WTF/wtf/spi/darwin/SandboxSPI.h b/Source/WTF/wtf/spi/darwin/SandboxSPI.h
index 38c390f..d71303a 100644
--- a/Source/WTF/wtf/spi/darwin/SandboxSPI.h
+++ b/Source/WTF/wtf/spi/darwin/SandboxSPI.h
@@ -64,6 +64,7 @@
 char *sandbox_extension_issue_file(const char *extension_class, const char *path, uint32_t flags);
 char *sandbox_extension_issue_generic(const char *extension_class, uint32_t flags);
 char *sandbox_extension_issue_mach_to_process_by_pid(const char *extension_class, const char *name, uint32_t flags, pid_t);
+char *sandbox_extension_issue_file_to_process_by_pid(const char *extension_class, const char *path, uint32_t flags, pid_t);
 int sandbox_check(pid_t, const char *operation, enum sandbox_filter_type, ...);
 int sandbox_check_by_audit_token(audit_token_t, const char *operation, enum sandbox_filter_type, ...);
 int sandbox_container_path_for_pid(pid_t, char *buffer, size_t bufsize);
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 9274dd9..0a78908 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,20 @@
+2019-08-08  Per Arne Vollan  <pvollan@apple.com>
+
+        [Mac] Use the PID of the WebContent process when issuing local file read sandbox extensions
+        https://bugs.webkit.org/show_bug.cgi?id=200543
+
+        Reviewed by Brent Fulgham.
+
+        Adopt SPI to issue a process-specific sandbox extension for local file read, passing it the process
+        identifier of the WebContent process.
+
+        * Shared/Cocoa/SandboxExtensionCocoa.mm:
+        (WebKit::SandboxExtensionImpl::sandboxExtensionForType):
+        (WebKit::SandboxExtension::createHandleForReadByPid):
+        * Shared/SandboxExtension.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::maybeInitializeSandboxExtensionHandle):
+
 2019-08-08  Said Abou-Hallawa  <sabouhallawa@apple.com>
 
         [iOS] Position image information should respect the image orientation
diff --git a/Source/WebKit/Shared/Cocoa/SandboxExtensionCocoa.mm b/Source/WebKit/Shared/Cocoa/SandboxExtensionCocoa.mm
index 7b6d52b..56a783a 100644
--- a/Source/WebKit/Shared/Cocoa/SandboxExtensionCocoa.mm
+++ b/Source/WebKit/Shared/Cocoa/SandboxExtensionCocoa.mm
@@ -100,6 +100,14 @@
 #endif
         case SandboxExtension::Type::Generic:
             return sandbox_extension_issue_generic(path, 0);
+        case SandboxExtension::Type::ReadByPid:
+#if HAVE(SANDBOX_ISSUE_READ_EXTENSION_TO_PROCESS_BY_PID)
+            return sandbox_extension_issue_file_to_process_by_pid(APP_SANDBOX_READ, path, 0, pid.value());
+#else
+            UNUSED_PARAM(pid);
+            ASSERT_NOT_REACHED();
+            return nullptr;
+#endif
         }
     }
 
@@ -336,6 +344,19 @@
     return true;
 }
 
+bool SandboxExtension::createHandleForReadByPid(const String& path, ProcessID pid, Handle& handle)
+{
+    ASSERT(!handle.m_sandboxExtension);
+    
+    handle.m_sandboxExtension = SandboxExtensionImpl::create(path.utf8().data(), Type::ReadByPid, pid);
+    if (!handle.m_sandboxExtension) {
+        WTFLogAlways("Could not create a '%s' sandbox extension", path.utf8().data());
+        return false;
+    }
+    
+    return true;
+}
+
 SandboxExtension::SandboxExtension(const Handle& handle)
     : m_sandboxExtension(WTFMove(handle.m_sandboxExtension))
 {
diff --git a/Source/WebKit/Shared/SandboxExtension.h b/Source/WebKit/Shared/SandboxExtension.h
index 693bd70..bae4a56 100644
--- a/Source/WebKit/Shared/SandboxExtension.h
+++ b/Source/WebKit/Shared/SandboxExtension.h
@@ -49,6 +49,7 @@
         ReadWrite,
         Mach,
         Generic,
+        ReadByPid
     };
 
     class Handle {
@@ -104,6 +105,7 @@
     static String createHandleForTemporaryFile(const String& prefix, Type, Handle&);
     static bool createHandleForGenericExtension(const String& extensionClass, Handle&);
     static bool createHandleForMachLookupByPid(const String& service, ProcessID, Handle&);
+    static bool createHandleForReadByPid(const String& path, ProcessID, Handle&);
     ~SandboxExtension();
 
     bool consume();
diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp
index 6f0efa9..8bcbb8a 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.cpp
+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp
@@ -1076,7 +1076,11 @@
     // Inspector resources are in a directory with assumed access.
     ASSERT_WITH_SECURITY_IMPLICATION(!WebKit::isInspectorPage(*this));
 
+#if PLATFORM(MAC) && HAVE(SANDBOX_ISSUE_READ_EXTENSION_TO_PROCESS_BY_PID)
+    if (SandboxExtension::createHandleForReadByPid("/", processIdentifier(), sandboxExtensionHandle)) {
+#else
     if (SandboxExtension::createHandle("/", SandboxExtension::Type::ReadOnly, sandboxExtensionHandle)) {
+#endif
         willAcquireUniversalFileReadSandboxExtension(process);
         return;
     }
@@ -1089,7 +1093,13 @@
     // We failed to issue an universal file read access sandbox, fall back to issuing one for the base URL instead.
     auto baseURL = URL(URL(), url.baseAsString());
     auto basePath = baseURL.fileSystemPath();
-    if (!basePath.isNull() && SandboxExtension::createHandle(basePath, SandboxExtension::Type::ReadOnly, sandboxExtensionHandle))
+    if (basePath.isNull())
+        return;
+#if PLATFORM(MAC) && HAVE(SANDBOX_ISSUE_READ_EXTENSION_TO_PROCESS_BY_PID)
+    if (SandboxExtension::createHandleForReadByPid(basePath, processIdentifier(), sandboxExtensionHandle))
+#else
+    if (SandboxExtension::createHandle(basePath, SandboxExtension::Type::ReadOnly, sandboxExtensionHandle))
+#endif
         m_process->assumeReadAccessToBaseURL(*this, baseURL);
 }