[iOS] Deny mach lookup access to content filter service in the WebContent sandbox
authorpvollan@apple.com <pvollan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Dec 2019 19:09:12 +0000 (19:09 +0000)
committerpvollan@apple.com <pvollan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Dec 2019 19:09:12 +0000 (19:09 +0000)
https://bugs.webkit.org/show_bug.cgi?id=205077

Reviewed by Brent Fulgham.

Source/WebCore:

Add a global flag to ParentalControlsContentFilter to indicate whether the Web content filter extension has
been consumed. If the flag has been set, there is no need to check [WebFilterEvaluator isManagedSession],
since the flag will tell if filtering is required.

The API test ContentFiltering.LazilyLoadPlatformFrameworks has been modified to pass after this change.

* WebCore.xcodeproj/project.pbxproj:
* platform/cocoa/ParentalControlsContentFilter.h:
* platform/cocoa/ParentalControlsContentFilter.mm:
(WebCore::ParentalControlsContentFilter::enabled):
(WebCore::ParentalControlsContentFilter::setHasConsumedSandboxExtension):

Source/WebKit:

Mach lookup access to the content filter service in the WebContent process is only needed if
[WebFilterEvaluator isManagedSession] evaluates to true. If this is the case, issue the needed
mach lookup sandbox extension to the WebContent process, where it will be consumed.

* Resources/SandboxProfiles/ios/com.apple.WebKit.WebContent.sb:
* Shared/WebProcessCreationParameters.cpp:
(WebKit::WebProcessCreationParameters::encode const):
(WebKit::WebProcessCreationParameters::decode):
* Shared/WebProcessCreationParameters.h:
* UIProcess/Cocoa/WebProcessPoolCocoa.mm:
(WebKit::WebProcessPool::platformInitializeWebProcess):
* WebProcess/cocoa/WebProcessCocoa.mm:
(WebKit::WebProcess::platformInitializeWebProcess):

Tools:

With this patch, the WebContentAnalysis framework will not be loaded in the WebContent process unless
[WebFilterEvaluator isManagedSession] returns YES. Swizzle this method to return YES in the UI process.

* TestWebKitAPI/Tests/WebKitCocoa/ContentFiltering.mm:
(isManagedSession):
(TEST):

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

12 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/platform/cocoa/ParentalControlsContentFilter.h
Source/WebCore/platform/cocoa/ParentalControlsContentFilter.mm
Source/WebKit/ChangeLog
Source/WebKit/Resources/SandboxProfiles/ios/com.apple.WebKit.WebContent.sb
Source/WebKit/Shared/WebProcessCreationParameters.cpp
Source/WebKit/Shared/WebProcessCreationParameters.h
Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/ContentFiltering.mm

index a233e94..16782d8 100644 (file)
@@ -1,3 +1,22 @@
+2019-12-12  Per Arne Vollan  <pvollan@apple.com>
+
+        [iOS] Deny mach lookup access to content filter service in the WebContent sandbox
+        https://bugs.webkit.org/show_bug.cgi?id=205077
+
+        Reviewed by Brent Fulgham.
+
+        Add a global flag to ParentalControlsContentFilter to indicate whether the Web content filter extension has
+        been consumed. If the flag has been set, there is no need to check [WebFilterEvaluator isManagedSession],
+        since the flag will tell if filtering is required.
+
+        The API test ContentFiltering.LazilyLoadPlatformFrameworks has been modified to pass after this change.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/cocoa/ParentalControlsContentFilter.h:
+        * platform/cocoa/ParentalControlsContentFilter.mm:
+        (WebCore::ParentalControlsContentFilter::enabled):
+        (WebCore::ParentalControlsContentFilter::setHasConsumedSandboxExtension):
+
 2019-12-12  Zalan Bujtas  <zalan@apple.com>
 
         [LFC][IFC] Fix fast/text/whitespace/023.html
index ffd5e57..9958df2 100644 (file)
                A17FEE641F8893220021E811 /* PaymentSessionBase.h in Headers */ = {isa = PBXBuildFile; fileRef = A17FEE631F8893220021E811 /* PaymentSessionBase.h */; };
                A180AD5B219F81B000DC039A /* WebCoreAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = A17E4F26219BC01600E1C7EE /* WebCoreAdditions.mm */; };
                A185B42A1E8211A100DC9118 /* LegacyPreviewLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = A185B4281E8211A100DC9118 /* LegacyPreviewLoader.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               A18890AF1AA13F250026C301 /* ParentalControlsContentFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = A18890AD1AA13F250026C301 /* ParentalControlsContentFilter.h */; };
+               A18890AF1AA13F250026C301 /* ParentalControlsContentFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = A18890AD1AA13F250026C301 /* ParentalControlsContentFilter.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A1956F1C2331A6770057E9D2 /* JSApplePayCancelEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = A1956F1B2331A6460057E9D2 /* JSApplePayCancelEvent.h */; };
                A1956F202331A8C70057E9D2 /* ApplePaySessionError.h in Headers */ = {isa = PBXBuildFile; fileRef = A1956F1D2331A8C70057E9D2 /* ApplePaySessionError.h */; };
                A1956F232331ACF20057E9D2 /* WHLSLReplaceWith.h in Headers */ = {isa = PBXBuildFile; fileRef = 3351F70B22CAD8DA0015B40D /* WHLSLReplaceWith.h */; };
index ae27bfd..1b3685d 100644 (file)
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef ParentalControlsContentFilter_h
-#define ParentalControlsContentFilter_h
+#pragma once
 
 #include "PlatformContentFilter.h"
 #include <wtf/Compiler.h>
@@ -49,6 +48,11 @@ public:
 #if ENABLE(CONTENT_FILTERING)
     ContentFilterUnblockHandler unblockHandler() const override;
 #endif
+    
+#if PLATFORM(IOS)
+    WEBCORE_EXPORT static void setHasConsumedSandboxExtension(bool);
+#endif
+
 private:
     static bool enabled();
 
@@ -57,8 +61,16 @@ private:
 
     RetainPtr<WebFilterEvaluator> m_webFilterEvaluator;
     RetainPtr<NSData> m_replacementData;
+
+#if PLATFORM(IOS)
+    enum class SandboxExtensionState : uint8_t {
+        Consumed,
+        NotConsumed,
+        NotSet
+    };
+
+    WEBCORE_EXPORT static SandboxExtensionState m_sandboxExtensionState;
+#endif
 };
     
 } // namespace WebCore
-
-#endif // ParentalControlsContentFilter_h
index 0d2a621..4c5baf8 100644 (file)
@@ -41,9 +41,28 @@ SOFT_LINK_CLASS(WebContentAnalysis, WebFilterEvaluator);
 
 namespace WebCore {
 
+#if PLATFORM(IOS)
+ParentalControlsContentFilter::SandboxExtensionState ParentalControlsContentFilter::m_sandboxExtensionState = SandboxExtensionState::NotSet;
+#endif
+
 bool ParentalControlsContentFilter::enabled()
 {
+#if PLATFORM(IOS)
+    bool enabled = false;
+    switch (m_sandboxExtensionState) {
+    case SandboxExtensionState::Consumed:
+        enabled = true;
+        break;
+    case SandboxExtensionState::NotConsumed:
+        enabled = false;
+        break;
+    case SandboxExtensionState::NotSet:
+        enabled = [getWebFilterEvaluatorClass() isManagedSession];
+        break;
+    }
+#else
     bool enabled = [getWebFilterEvaluatorClass() isManagedSession];
+#endif
     LOG(ContentFiltering, "ParentalControlsContentFilter is %s.\n", enabled ? "enabled" : "not enabled");
     return enabled;
 }
@@ -128,6 +147,13 @@ void ParentalControlsContentFilter::updateFilterState()
 #endif
 }
 
+#if PLATFORM(IOS)
+void ParentalControlsContentFilter::setHasConsumedSandboxExtension(bool hasConsumedSandboxExtension)
+{
+    m_sandboxExtensionState = (hasConsumedSandboxExtension ? SandboxExtensionState::Consumed : SandboxExtensionState::NotConsumed);
+}
+#endif
+
 } // namespace WebCore
 
 #endif // HAVE(PARENTAL_CONTROLS)
index c835feb..db57eb9 100644 (file)
@@ -1,3 +1,24 @@
+2019-12-12  Per Arne Vollan  <pvollan@apple.com>
+
+        [iOS] Deny mach lookup access to content filter service in the WebContent sandbox
+        https://bugs.webkit.org/show_bug.cgi?id=205077
+
+        Reviewed by Brent Fulgham.
+
+        Mach lookup access to the content filter service in the WebContent process is only needed if
+        [WebFilterEvaluator isManagedSession] evaluates to true. If this is the case, issue the needed
+        mach lookup sandbox extension to the WebContent process, where it will be consumed.
+
+        * Resources/SandboxProfiles/ios/com.apple.WebKit.WebContent.sb:
+        * Shared/WebProcessCreationParameters.cpp:
+        (WebKit::WebProcessCreationParameters::encode const):
+        (WebKit::WebProcessCreationParameters::decode):
+        * Shared/WebProcessCreationParameters.h:
+        * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
+        (WebKit::WebProcessPool::platformInitializeWebProcess):
+        * WebProcess/cocoa/WebProcessCocoa.mm:
+        (WebKit::WebProcess::platformInitializeWebProcess):
+
 2019-12-12  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         WebDriver: tests is_element_enabled/enabled.py::test_fieldset_disabled_descendant are failing
index ae1dc64..3f54541 100644 (file)
 (allow mach-lookup
     (require-all
         (extension "com.apple.webkit.extension.mach")
-        (global-name "com.apple.iphone.axserver-systemwide" "com.apple.tccd" "com.apple.AGXCompilerService" "com.apple.nehelper" "com.apple.nesessionmanager.content-filter")))
+        (global-name "com.apple.iphone.axserver-systemwide" "com.apple.tccd" "com.apple.AGXCompilerService" "com.apple.nehelper" "com.apple.nesessionmanager.content-filter" "com.apple.uikit.viewservice.com.apple.WebContentFilter.remoteUI")))
 
 (media-capture-support)
 
index 48667f7..e3b682c 100644 (file)
@@ -162,6 +162,7 @@ void WebProcessCreationParameters::encode(IPC::Encoder& encoder) const
     
 #if PLATFORM(IOS)
     encoder << compilerServiceExtensionHandle;
+    encoder << contentFilterExtensionHandle;
 #endif
     
 #if PLATFORM(COCOA)
@@ -406,6 +407,12 @@ bool WebProcessCreationParameters::decode(IPC::Decoder& decoder, WebProcessCreat
     if (!compilerServiceExtensionHandle)
         return false;
     parameters.compilerServiceExtensionHandle = WTFMove(*compilerServiceExtensionHandle);
+
+    Optional<Optional<SandboxExtension::Handle>> contentFilterExtensionHandle;
+    decoder >> contentFilterExtensionHandle;
+    if (!contentFilterExtensionHandle)
+        return false;
+    parameters.contentFilterExtensionHandle = WTFMove(*contentFilterExtensionHandle);
 #endif
 
 #if PLATFORM(COCOA)
index 4eed7f1..0625c00 100644 (file)
@@ -200,6 +200,7 @@ struct WebProcessCreationParameters {
     
 #if PLATFORM(IOS)
     Optional<SandboxExtension::Handle> compilerServiceExtensionHandle;
+    Optional<SandboxExtension::Handle> contentFilterExtensionHandle;
 #endif
 
 #if PLATFORM(COCOA)
index 3d38450..bd3657b 100644 (file)
 #endif
 
 #if PLATFORM(IOS)
+#import <pal/spi/cocoa/WebFilterEvaluatorSPI.h>
 #import <sys/utsname.h>
+
+SOFT_LINK_PRIVATE_FRAMEWORK(WebContentAnalysis);
+SOFT_LINK_CLASS(WebContentAnalysis, WebFilterEvaluator);
 #endif
 
 #if PLATFORM(COCOA)
@@ -312,6 +316,14 @@ void WebProcessPool::platformInitializeWebProcess(const WebProcessProxy& process
         parameters.neSessionManagerExtensionHandle = WTFMove(handle);
     }
 #endif
+    
+#if PLATFORM(IOS)
+    if ([getWebFilterEvaluatorClass() isManagedSession]) {
+        SandboxExtension::Handle handle;
+        SandboxExtension::createHandleForMachLookup("com.apple.uikit.viewservice.com.apple.WebContentFilter.remoteUI", WTF::nullopt, handle);
+        parameters.contentFilterExtensionHandle = WTFMove(handle);
+    }
+#endif
 }
 
 void WebProcessPool::platformInitializeNetworkProcess(NetworkProcessCreationParameters& parameters)
index b92e444..98f1430 100644 (file)
@@ -81,6 +81,7 @@
 
 #if PLATFORM(IOS)
 #import "UIKitSPI.h"
+#import <WebCore/ParentalControlsContentFilter.h>
 #endif
 
 #if PLATFORM(IOS_FAMILY)
@@ -229,6 +230,10 @@ void WebProcess::platformInitializeWebProcess(WebProcessCreationParameters& para
 #if PLATFORM(IOS)
     if (parameters.compilerServiceExtensionHandle)
         SandboxExtension::consumePermanently(*parameters.compilerServiceExtensionHandle);
+
+    if (parameters.contentFilterExtensionHandle)
+        SandboxExtension::consumePermanently(*parameters.contentFilterExtensionHandle);
+    ParentalControlsContentFilter::setHasConsumedSandboxExtension(parameters.contentFilterExtensionHandle.hasValue());
 #endif
     
 #if PLATFORM(COCOA)
index 891f7f0..9781826 100644 (file)
@@ -1,3 +1,17 @@
+2019-12-12  Per Arne Vollan  <pvollan@apple.com>
+
+        [iOS] Deny mach lookup access to content filter service in the WebContent sandbox
+        https://bugs.webkit.org/show_bug.cgi?id=205077
+
+        Reviewed by Brent Fulgham.
+
+        With this patch, the WebContentAnalysis framework will not be loaded in the WebContent process unless
+        [WebFilterEvaluator isManagedSession] returns YES. Swizzle this method to return YES in the UI process.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ContentFiltering.mm:
+        (isManagedSession):
+        (TEST):
+
 2019-12-12  Patrick Griffis  <pgriffis@igalia.com>
 
         [SOUP] Use new API for strict secure cookies
index 301dba5..d98fa44 100644 (file)
 #import <WebKit/_WKRemoteObjectInterface.h>
 #import <WebKit/_WKRemoteObjectRegistry.h>
 #import <pal/spi/cocoa/NEFilterSourceSPI.h>
+#import <pal/spi/cocoa/WebFilterEvaluatorSPI.h>
 #import <wtf/RetainPtr.h>
 #import <wtf/SoftLinking.h>
 
 SOFT_LINK_FRAMEWORK_OPTIONAL(NetworkExtension);
 SOFT_LINK_CLASS_OPTIONAL(NetworkExtension, NEFilterSource);
 
+SOFT_LINK_PRIVATE_FRAMEWORK(WebContentAnalysis);
+SOFT_LINK_CLASS(WebContentAnalysis, WebFilterEvaluator);
+
 using Decision = WebCore::MockContentFilterSettings::Decision;
 using DecisionPoint = WebCore::MockContentFilterSettings::DecisionPoint;
 
@@ -385,12 +389,21 @@ static BOOL filterRequired(id self, SEL _cmd)
     return YES;
 }
 
+static BOOL isManagedSession(id self, SEL _cmd)
+{
+    return YES;
+}
+
 TEST(ContentFiltering, LazilyLoadPlatformFrameworks)
 {
     // Swizzle [NEFilterSource filterRequired] to return YES in the UI process since NetworkExtension will not be loaded otherwise.
     Method method = class_getClassMethod(getNEFilterSourceClass(), @selector(filterRequired));
     method_setImplementation(method, reinterpret_cast<IMP>(filterRequired));
 
+    // Swizzle [WebFilterEvaluator isManagedSession] to return YES in the UI process since WebContentAnalysis will not be loaded otherwise.
+    method = class_getClassMethod(getWebFilterEvaluatorClass(), @selector(isManagedSession));
+    method_setImplementation(method, reinterpret_cast<IMP>(isManagedSession));
+
     @autoreleasepool {
         auto controller = adoptNS([[LazilyLoadPlatformFrameworksController alloc] init]);
         [controller expectParentalControlsLoaded:NO networkExtensionLoaded:NO];