[iOS] Create sandbox extension for "com.apple.tccd"
https://bugs.webkit.org/show_bug.cgi?id=204367
<rdar://problem/57330176>

Reviewed by Eric Carlson.

When camera or microphone access has been granted by the user, have the UI process create a sandbox extension
for "com.apple.tccd", and send it to the WebContent process. Also make sure the extension is created only once
for each WebContent process. Add telemetry to the tccd rule in the sandbox.

* Resources/SandboxProfiles/ios/com.apple.WebKit.WebContent.sb:
* UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
(WebKit::UserMediaPermissionRequestManagerProxy::finishGrantingRequest):
* UIProcess/UserMediaPermissionRequestManagerProxy.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::userMediaAccessWasGranted):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@253011 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index d3e0c68..9db954b 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,24 @@
+2019-12-02  Per Arne Vollan  <pvollan@apple.com>
+
+        [iOS] Create sandbox extension for "com.apple.tccd"
+        https://bugs.webkit.org/show_bug.cgi?id=204367
+        <rdar://problem/57330176>
+
+        Reviewed by Eric Carlson.
+
+        When camera or microphone access has been granted by the user, have the UI process create a sandbox extension
+        for "com.apple.tccd", and send it to the WebContent process. Also make sure the extension is created only once
+        for each WebContent process. Add telemetry to the tccd rule in the sandbox.
+
+        * Resources/SandboxProfiles/ios/com.apple.WebKit.WebContent.sb:
+        * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
+        (WebKit::UserMediaPermissionRequestManagerProxy::finishGrantingRequest):
+        * UIProcess/UserMediaPermissionRequestManagerProxy.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::userMediaAccessWasGranted):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
 2019-12-02  Louie Livon-Bemel  <llivonbemel@apple.com>
 
         Add helper methods for description and equality to text manipulation SPI
diff --git a/Source/WebKit/Resources/SandboxProfiles/ios/com.apple.WebKit.WebContent.sb b/Source/WebKit/Resources/SandboxProfiles/ios/com.apple.WebKit.WebContent.sb
index fbc9c27..1da6d37 100644
--- a/Source/WebKit/Resources/SandboxProfiles/ios/com.apple.WebKit.WebContent.sb
+++ b/Source/WebKit/Resources/SandboxProfiles/ios/com.apple.WebKit.WebContent.sb
@@ -628,7 +628,7 @@
     (global-name "com.apple.aggregated")
     (global-name "com.apple.cfprefsd.daemon"))
 
-(allow mach-lookup
+(allow mach-lookup (with report) (with telemetry)
     (global-name "com.apple.tccd"))
 
 (allow ipc-posix-shm-read*
@@ -964,7 +964,7 @@
 (allow mach-lookup
     (require-all
         (extension "com.apple.webkit.extension.mach")
-        (global-name "com.apple.iphone.axserver-systemwide")))
+        (global-name "com.apple.iphone.axserver-systemwide" "com.apple.tccd")))
 
 (media-capture-support)
 
diff --git a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp
index 5a8947a..4dbed53 100644
--- a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp
+++ b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp
@@ -239,7 +239,16 @@
     m_hasFilteredDeviceList = false;
 
     ++m_hasPendingCapture;
-    m_page.process().connection()->sendWithAsyncReply(Messages::WebPage::UserMediaAccessWasGranted { request.userMediaID(), request.audioDevice(), request.videoDevice(), request.deviceIdentifierHashSalt() }, [this, weakThis = makeWeakPtr(this)] {
+
+    SandboxExtension::Handle handle;
+#if PLATFORM(COCOA)
+    if (!m_hasCreatedSandboxExtensionForTCCD) {
+        SandboxExtension::createHandleForMachLookup("com.apple.tccd", m_page.process().connection()->getAuditToken(), handle);
+        m_hasCreatedSandboxExtensionForTCCD = true;
+    }
+#endif
+
+    m_page.process().connection()->sendWithAsyncReply(Messages::WebPage::UserMediaAccessWasGranted { request.userMediaID(), request.audioDevice(), request.videoDevice(), request.deviceIdentifierHashSalt(), handle }, [this, weakThis = makeWeakPtr(this)] {
         if (!weakThis)
             return;
         if (!--m_hasPendingCapture)
diff --git a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h
index 9203042..88142ed 100644
--- a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h
+++ b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h
@@ -154,6 +154,9 @@
     const void* m_logIdentifier;
 #endif
     bool m_hasFilteredDeviceList { false };
+#if PLATFORM(COCOA)
+    bool m_hasCreatedSandboxExtensionForTCCD { false };
+#endif
     uint64_t m_hasPendingCapture { 0 };
     Optional<bool> m_mockDevicesEnabledOverride;
 };
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
index d23e00c..f026ef4 100644
--- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
@@ -4168,8 +4168,10 @@
 
 #if ENABLE(MEDIA_STREAM)
 
-void WebPage::userMediaAccessWasGranted(uint64_t userMediaID, WebCore::CaptureDevice&& audioDevice, WebCore::CaptureDevice&& videoDevice, String&& mediaDeviceIdentifierHashSalt, CompletionHandler<void()>&& completionHandler)
+void WebPage::userMediaAccessWasGranted(uint64_t userMediaID, WebCore::CaptureDevice&& audioDevice, WebCore::CaptureDevice&& videoDevice, String&& mediaDeviceIdentifierHashSalt, SandboxExtension::Handle&& handle, CompletionHandler<void()>&& completionHandler)
 {
+    SandboxExtension::consumePermanently(handle);
+
     m_userMediaPermissionRequestManager->userMediaAccessWasGranted(userMediaID, WTFMove(audioDevice), WTFMove(videoDevice), WTFMove(mediaDeviceIdentifierHashSalt), WTFMove(completionHandler));
 }
 
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h
index f530c7d..69838b0 100644
--- a/Source/WebKit/WebProcess/WebPage/WebPage.h
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.h
@@ -1513,7 +1513,7 @@
     void didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed);
 
 #if ENABLE(MEDIA_STREAM)
-    void userMediaAccessWasGranted(uint64_t userMediaID, WebCore::CaptureDevice&& audioDeviceUID, WebCore::CaptureDevice&& videoDeviceUID, String&& mediaDeviceIdentifierHashSalt, CompletionHandler<void()>&&);
+    void userMediaAccessWasGranted(uint64_t userMediaID, WebCore::CaptureDevice&& audioDeviceUID, WebCore::CaptureDevice&& videoDeviceUID, String&& mediaDeviceIdentifierHashSalt, SandboxExtension::Handle&&, CompletionHandler<void()>&&);
     void userMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String&& invalidConstraint);
 
 #endif
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
index 0f2c3ac..3e891f81 100644
--- a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
@@ -359,7 +359,7 @@
 
 #if ENABLE(MEDIA_STREAM)
     # MediaSteam
-    UserMediaAccessWasGranted(uint64_t userMediaID, WebCore::CaptureDevice audioDevice, WebCore::CaptureDevice videoDevice, String mediaDeviceIdentifierHashSalt) -> () Async
+    UserMediaAccessWasGranted(uint64_t userMediaID, WebCore::CaptureDevice audioDevice, WebCore::CaptureDevice videoDevice, String mediaDeviceIdentifierHashSalt, WebKit::SandboxExtension::Handle sandboxExtensionHandle) -> () Async
     UserMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String invalidConstraint)
     CaptureDevicesChanged()
 #endif