[macOS] Deny mach-lookup access to "com.apple.lsd.mapdb" in sandbox
https://bugs.webkit.org/show_bug.cgi?id=209814

Reviewed by Darin Adler.

Source/WebKit:

This was done for iOS in <https://trac.webkit.org/changeset/258915>, and in order to be able to do this
on macOS, checking in with Launch Services and updating the process name needs to be done after the
Launch Services database mapping has been done in WebProcess::platformInitializeWebProcess. Also, the
previous call to RegisterApplication has been replaced with a call to launchServicesCheckIn, since
RegisterApplication is an AppKit function, and should be avoided since the WebContent process is not
a NSApplication anymore.

Test: fast/sandbox/mac/sandbox-mach-lookup.html

* Shared/mac/AuxiliaryProcessMac.mm:
(WebKit::AuxiliaryProcess::launchServicesCheckIn):
* UIProcess/Cocoa/WebProcessPoolCocoa.mm:
(WebKit::WebProcessPool::platformInitializeWebProcess):
* WebProcess/cocoa/WebProcessCocoa.mm:
(WebKit::WebProcess::platformInitializeWebProcess):
(WebKit::WebProcess::initializeProcessName):
(WebKit::WebProcess::updateProcessName):
(WebKit::WebProcess::platformInitializeProcess):
* WebProcess/com.apple.WebProcess.sb.in:

LayoutTests:

* fast/sandbox/mac/sandbox-mach-lookup-expected.txt:
* fast/sandbox/mac/sandbox-mach-lookup.html:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@259366 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index f37e193..1e21368 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2020-04-01  Per Arne Vollan  <pvollan@apple.com>
+
+        [macOS] Deny mach-lookup access to "com.apple.lsd.mapdb" in sandbox
+        https://bugs.webkit.org/show_bug.cgi?id=209814
+
+        Reviewed by Darin Adler.
+
+        * fast/sandbox/mac/sandbox-mach-lookup-expected.txt:
+        * fast/sandbox/mac/sandbox-mach-lookup.html:
+
 2020-04-01  Jason Lawrence  <lawrence.j@apple.com>
 
         [ Mac wk1 Debug ] inspector/page/overrideSetting-ICECandidateFilteringEnabled.html is flaky timing out.
diff --git a/LayoutTests/fast/sandbox/mac/sandbox-mach-lookup-expected.txt b/LayoutTests/fast/sandbox/mac/sandbox-mach-lookup-expected.txt
index 8807cd0..a136a1c 100644
--- a/LayoutTests/fast/sandbox/mac/sandbox-mach-lookup-expected.txt
+++ b/LayoutTests/fast/sandbox/mac/sandbox-mach-lookup-expected.txt
@@ -8,4 +8,5 @@
 PASS internals.hasSandboxMachLookupAccessToGlobalName("com.apple.WebKit.WebContent", "com.apple.nesessionmanager") is false
 PASS internals.hasSandboxMachLookupAccessToGlobalName("com.apple.WebKit.WebContent", "com.apple.nesessionmanager.content-filter") is false
 PASS internals.hasSandboxMachLookupAccessToGlobalName("com.apple.WebKit.WebContent", "com.apple.system.logger") is false
+PASS internals.hasSandboxMachLookupAccessToGlobalName("com.apple.WebKit.WebContent", "com.apple.lsd.mapdb") is false
 
diff --git a/LayoutTests/fast/sandbox/mac/sandbox-mach-lookup.html b/LayoutTests/fast/sandbox/mac/sandbox-mach-lookup.html
index 00c2f5a..9462915 100644
--- a/LayoutTests/fast/sandbox/mac/sandbox-mach-lookup.html
+++ b/LayoutTests/fast/sandbox/mac/sandbox-mach-lookup.html
@@ -11,6 +11,7 @@
     shouldBeFalse("internals.hasSandboxMachLookupAccessToGlobalName(\"com.apple.WebKit.WebContent\", \"com.apple.nesessionmanager\")");
     shouldBeFalse("internals.hasSandboxMachLookupAccessToGlobalName(\"com.apple.WebKit.WebContent\", \"com.apple.nesessionmanager.content-filter\")");
     shouldBeFalse("internals.hasSandboxMachLookupAccessToGlobalName(\"com.apple.WebKit.WebContent\", \"com.apple.system.logger\")");
+    shouldBeFalse("internals.hasSandboxMachLookupAccessToGlobalName(\"com.apple.WebKit.WebContent\", \"com.apple.lsd.mapdb\")");
 }
 </script>
 </head>
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 3307649..19a70eb 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,30 @@
+2020-04-01  Per Arne Vollan  <pvollan@apple.com>
+
+        [macOS] Deny mach-lookup access to "com.apple.lsd.mapdb" in sandbox
+        https://bugs.webkit.org/show_bug.cgi?id=209814
+
+        Reviewed by Darin Adler.
+
+        This was done for iOS in <https://trac.webkit.org/changeset/258915>, and in order to be able to do this
+        on macOS, checking in with Launch Services and updating the process name needs to be done after the
+        Launch Services database mapping has been done in WebProcess::platformInitializeWebProcess. Also, the
+        previous call to RegisterApplication has been replaced with a call to launchServicesCheckIn, since
+        RegisterApplication is an AppKit function, and should be avoided since the WebContent process is not
+        a NSApplication anymore.
+
+        Test: fast/sandbox/mac/sandbox-mach-lookup.html
+
+        * Shared/mac/AuxiliaryProcessMac.mm:
+        (WebKit::AuxiliaryProcess::launchServicesCheckIn):
+        * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
+        (WebKit::WebProcessPool::platformInitializeWebProcess):
+        * WebProcess/cocoa/WebProcessCocoa.mm:
+        (WebKit::WebProcess::platformInitializeWebProcess):
+        (WebKit::WebProcess::initializeProcessName):
+        (WebKit::WebProcess::updateProcessName):
+        (WebKit::WebProcess::platformInitializeProcess):
+        * WebProcess/com.apple.WebProcess.sb.in:
+
 2020-04-01  Chris Dumez  <cdumez@apple.com>
 
         Regression(r257963) didFailProvisionalNavigation delegate no longer gets called when cancelling a cross-site provisional navigation
diff --git a/Source/WebKit/Shared/mac/AuxiliaryProcessMac.mm b/Source/WebKit/Shared/mac/AuxiliaryProcessMac.mm
index 78f9c05..6010a95 100644
--- a/Source/WebKit/Shared/mac/AuxiliaryProcessMac.mm
+++ b/Source/WebKit/Shared/mac/AuxiliaryProcessMac.mm
@@ -75,6 +75,9 @@
 typedef bool (^LSServerConnectionAllowedBlock) ( CFDictionaryRef optionsRef );
 extern "C" void _LSSetApplicationLaunchServicesServerConnectionStatus(uint64_t flags, LSServerConnectionAllowedBlock block);
 extern "C" CFDictionaryRef _LSApplicationCheckIn(LSSessionID sessionID, CFDictionaryRef applicationInfo);
+#if HAVE(CSCHECKFIXDISABLE)
+extern "C" void _CSCheckFixDisable();
+#endif
 
 namespace WebKit {
 using namespace WebCore;
@@ -151,6 +154,11 @@
 
 void AuxiliaryProcess::launchServicesCheckIn()
 {
+#if HAVE(CSCHECKFIXDISABLE)
+    // _CSCheckFixDisable() needs to be called before checking in with Launch Services.
+    _CSCheckFixDisable();
+#endif
+
     _LSSetApplicationLaunchServicesServerConnectionStatus(0, 0);
     RetainPtr<CFDictionaryRef> unused = _LSApplicationCheckIn(kLSDefaultSessionID, CFBundleGetInfoDictionary(CFBundleGetMainBundle()));
 }
diff --git a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
index 9f945509..abdf894 100644
--- a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
+++ b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
@@ -406,6 +406,10 @@
     parameters.systemHasBattery = systemHasBattery();
     parameters.mimeTypesMap = commonMimeTypesMap();
     parameters.mapUTIFromMIMEType = createUTIFromMIMETypeMap();
+
+    SandboxExtension::Handle mapDBHandle;
+    SandboxExtension::createHandleForMachLookup("com.apple.lsd.mapdb", WTF::nullopt, mapDBHandle, SandboxExtension::Flags::NoReport);
+    parameters.mapDBExtensionHandle = WTFMove(mapDBHandle);
 #endif
     
 #if PLATFORM(IOS)
@@ -426,10 +430,6 @@
     if (WebCore::IOSApplication::isMobileSafari())
         parameters.vectorOfUTTypeItem = createVectorOfUTTypeItem();
 #endif
-
-    SandboxExtension::Handle mapDBHandle;
-    SandboxExtension::createHandleForMachLookup("com.apple.lsd.mapdb", WTF::nullopt, mapDBHandle, SandboxExtension::Flags::NoReport);
-    parameters.mapDBExtensionHandle = WTFMove(mapDBHandle);
 #endif
     
     // Allow microphone access if either preference is set because WebRTC requires microphone access.
diff --git a/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm b/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm
index 5e19917..94aead9 100644
--- a/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm
+++ b/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm
@@ -134,10 +134,6 @@
 #import <os/state_private.h>
 #endif
 
-#if HAVE(CSCHECKFIXDISABLE)
-extern "C" void _CSCheckFixDisable();
-#endif
-
 #define RELEASE_LOG_SESSION_ID (m_sessionID ? m_sessionID->toUInt64() : 0)
 #define RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, "%p - [sessionID=%" PRIu64 "] WebProcess::" fmt, this, RELEASE_LOG_SESSION_ID, ##__VA_ARGS__)
 #define RELEASE_LOG_ERROR_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_ERROR_IF(isAlwaysOnLoggingAllowed(), channel, "%p - [sessionID=%" PRIu64 "] WebProcess::" fmt, this, RELEASE_LOG_SESSION_ID, ##__VA_ARGS__)
@@ -167,6 +163,18 @@
 
 void WebProcess::platformInitializeWebProcess(WebProcessCreationParameters& parameters)
 {
+    // Map Launch Services database. This should be done as early as possible, as the mapping will fail
+    // if 'com.apple.lsd.mapdb' is being accessed before this.
+    if (parameters.mapDBExtensionHandle) {
+        auto extension = SandboxExtension::create(WTFMove(*parameters.mapDBExtensionHandle));
+        bool ok = extension->consume();
+        ASSERT_UNUSED(ok, ok);
+        // Perform API calls which will communicate with the database mapping service, and map the database.
+        auto uti = adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, CFSTR("text/html"), 0));
+        ok = extension->revoke();
+        ASSERT_UNUSED(ok, ok);
+    }
+
 #if !LOG_DISABLED || !RELEASE_LOG_DISABLED
     WebCore::initializeLogChannelsIfNecessary(parameters.webCoreLoggingChannels);
     WebKit::initializeLogChannelsIfNecessary(parameters.webKitLoggingChannels);
@@ -273,16 +281,6 @@
         SandboxExtension::consumePermanently(*parameters.neSessionManagerExtensionHandle);
     NetworkExtensionContentFilter::setHasConsumedSandboxExtensions(parameters.neHelperExtensionHandle.hasValue() && parameters.neSessionManagerExtensionHandle.hasValue());
 
-    if (parameters.mapDBExtensionHandle) {
-        auto extension = SandboxExtension::create(WTFMove(*parameters.mapDBExtensionHandle));
-        bool ok = extension->consume();
-        ASSERT_UNUSED(ok, ok);
-        // Perform API calls which will communicate with the database mapping service, and map the database.
-        auto uti = adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, CFSTR("text/html"), 0));
-        ok = extension->revoke();
-        ASSERT_UNUSED(ok, ok);
-    }
-
     setSystemHasBattery(parameters.systemHasBattery);
 
     if (parameters.mimeTypesMap)
@@ -317,6 +315,8 @@
 #endif
 
     WebCore::sleepDisablerClient() = makeUnique<WebSleepDisablerClient>();
+
+    updateProcessName();
 }
 
 void WebProcess::platformSetWebsiteDataStoreParameters(WebProcessDataStoreParameters&& parameters)
@@ -335,23 +335,26 @@
     }
 }
 
-void WebProcess::initializeProcessName(const AuxiliaryProcessInitializationParameters&)
+void WebProcess::initializeProcessName(const AuxiliaryProcessInitializationParameters& parameters)
 {
 #if PLATFORM(MAC)
-#if HAVE(CSCHECKFIXDISABLE)
-    // _CSCheckFixDisable() needs to be called before checking in with Launch Services.
-    _CSCheckFixDisable();
-#endif
-    // This is necessary so that we are able to set the process' display name.
-    _RegisterApplication(nullptr, nullptr);
-
-    updateProcessName();
+    m_uiProcessName = parameters.uiProcessName;
+#else
+    UNUSED_PARAM(parameters);
 #endif
 }
 
 void WebProcess::updateProcessName()
 {
 #if PLATFORM(MAC)
+    static std::once_flag onceFlag;
+    std::call_once(
+        onceFlag,
+        [this] {
+            // Checking in with Launch Services is necessary to be able to set the process' display name.
+            launchServicesCheckIn();
+    });
+
     NSString *applicationName;
     switch (m_processType) {
     case ProcessType::Inspector:
@@ -521,8 +524,6 @@
         launchServicesCheckIn();
     }
 #endif // ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
-
-    m_uiProcessName = parameters.uiProcessName;
 #endif // PLATFORM(MAC)
 
     if (parameters.extraInitializationData.get("inspector-process"_s) == "1")
diff --git a/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in b/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in
index 8ceb57c..cd75c5f 100644
--- a/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in
+++ b/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in
@@ -679,10 +679,16 @@
 #endif
     (global-name "com.apple.PowerManagement.control")
     (global-name "com.apple.coreservices.launchservicesd")
-    (global-name "com.apple.lsd.mapdb")
     (global-name "com.apple.trustd.agent")
 )
 
+(deny mach-lookup
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101600
+    (with telemetry-backtrace)
+#endif
+    (global-name "com.apple.lsd.mapdb")
+)
+
 (allow mach-lookup
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500
     (with telemetry)