[iOS] Block the accessibility server when accessibility is not enabled.
authorpvollan@apple.com <pvollan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Mar 2019 20:27:24 +0000 (20:27 +0000)
committerpvollan@apple.com <pvollan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Mar 2019 20:27:24 +0000 (20:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195342

Reviewed by Brent Fulgham.

Source/WebKit:

By default, block the iOS accessibility server in the sandbox. If accessibility is enabled,
let the UI process issue a mach extension to the WebContent process. The UI process will
issue the mach extension the the WebContent process by its process identifier. The sandbox
extension handle is sent to the WebContent process to be consumed. The message will be sent
when the WebProcess has finished launching, and also when accessibility is turned on.

* Platform/spi/ios/AccessibilitySupportSPI.h:
* Resources/SandboxProfiles/ios/com.apple.WebKit.WebContent.sb:
* Shared/SandboxExtension.h:
* Shared/mac/SandboxExtensionMac.mm:
(WebKit::SandboxExtensionImpl::create):
(WebKit::SandboxExtensionImpl::sandboxExtensionForType):
(WebKit::SandboxExtensionImpl::SandboxExtensionImpl):
(WebKit::SandboxExtension::createHandleForMachLookupByPid):
* UIProcess/Cocoa/WebProcessPoolCocoa.mm:
(WebKit::WebProcessPool::registerNotificationObservers):
(WebKit::WebProcessPool::unregisterNotificationObservers):
* UIProcess/WebProcessPool.h:
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::didFinishLaunching):
* UIProcess/WebProcessProxy.h:
* UIProcess/ios/WebProcessProxyIOS.mm:
(WebKit::WebProcessProxy::unblockAccessibilityServerIfNeeded):
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::unblockAccessibilityServer):
* WebProcess/WebProcess.h:
* WebProcess/WebProcess.messages.in:

Source/WTF:

Add SPI to issue a mach extension to a process by pid.

* wtf/spi/darwin/SandboxSPI.h:

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

15 files changed:
Source/WTF/ChangeLog
Source/WTF/wtf/spi/darwin/SandboxSPI.h
Source/WebKit/ChangeLog
Source/WebKit/Platform/spi/ios/AccessibilitySupportSPI.h
Source/WebKit/Resources/SandboxProfiles/ios/com.apple.WebKit.WebContent.sb
Source/WebKit/Shared/SandboxExtension.h
Source/WebKit/Shared/mac/SandboxExtensionMac.mm
Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
Source/WebKit/UIProcess/WebProcessPool.h
Source/WebKit/UIProcess/WebProcessProxy.cpp
Source/WebKit/UIProcess/WebProcessProxy.h
Source/WebKit/UIProcess/ios/WebProcessProxyIOS.mm
Source/WebKit/WebProcess/WebProcess.cpp
Source/WebKit/WebProcess/WebProcess.h
Source/WebKit/WebProcess/WebProcess.messages.in

index 99bf757..05c85f3 100644 (file)
@@ -1,3 +1,14 @@
+2019-03-15  Per Arne Vollan  <pvollan@apple.com>
+
+        [iOS] Block the accessibility server when accessibility is not enabled.
+        https://bugs.webkit.org/show_bug.cgi?id=195342
+
+        Reviewed by Brent Fulgham.
+
+        Add SPI to issue a mach extension to a process by pid.
+
+        * wtf/spi/darwin/SandboxSPI.h:
+
 2019-03-13  Sam Weinig  <sam@webkit.org>
 
         Add utility function to allow easy reverse range-based iteration of a container
index b2681b4..38c390f 100644 (file)
@@ -63,6 +63,7 @@ extern const enum sandbox_filter_type SANDBOX_CHECK_NO_REPORT;
 
 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);
 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);
index 72474c0..095891d 100644 (file)
@@ -1,3 +1,38 @@
+2019-03-15  Per Arne Vollan  <pvollan@apple.com>
+
+        [iOS] Block the accessibility server when accessibility is not enabled.
+        https://bugs.webkit.org/show_bug.cgi?id=195342
+
+        Reviewed by Brent Fulgham.
+
+        By default, block the iOS accessibility server in the sandbox. If accessibility is enabled,
+        let the UI process issue a mach extension to the WebContent process. The UI process will
+        issue the mach extension the the WebContent process by its process identifier. The sandbox
+        extension handle is sent to the WebContent process to be consumed. The message will be sent
+        when the WebProcess has finished launching, and also when accessibility is turned on.
+
+        * Platform/spi/ios/AccessibilitySupportSPI.h:
+        * Resources/SandboxProfiles/ios/com.apple.WebKit.WebContent.sb:
+        * Shared/SandboxExtension.h:
+        * Shared/mac/SandboxExtensionMac.mm:
+        (WebKit::SandboxExtensionImpl::create):
+        (WebKit::SandboxExtensionImpl::sandboxExtensionForType):
+        (WebKit::SandboxExtensionImpl::SandboxExtensionImpl):
+        (WebKit::SandboxExtension::createHandleForMachLookupByPid):
+        * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
+        (WebKit::WebProcessPool::registerNotificationObservers):
+        (WebKit::WebProcessPool::unregisterNotificationObservers):
+        * UIProcess/WebProcessPool.h:
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::didFinishLaunching):
+        * UIProcess/WebProcessProxy.h:
+        * UIProcess/ios/WebProcessProxyIOS.mm:
+        (WebKit::WebProcessProxy::unblockAccessibilityServerIfNeeded):
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::unblockAccessibilityServer):
+        * WebProcess/WebProcess.h:
+        * WebProcess/WebProcess.messages.in:
+
 2019-03-15  Antti Koivisto  <antti@apple.com>
 
         Use Region for event region even when it is a rectangle
index 50ca2db..d360f79 100644 (file)
@@ -41,6 +41,8 @@ WTF_EXTERN_C_BEGIN
 #if PLATFORM(IOS_FAMILY)
 extern Boolean _AXSKeyRepeatEnabled();
 extern CFTimeInterval _AXSKeyRepeatDelay();
+extern Boolean _AXSApplicationAccessibilityEnabled();
+extern CFStringRef kAXSApplicationAccessibilityEnabledNotification;
 #endif
 
 #if ENABLE(ACCESSIBILITY_EVENTS)
index 2d2d490..06c8629 100644 (file)
     (global-name "com.apple.backboard.hid.focus")
     (global-name "com.apple.backboard.hid.services")
     (global-name "com.apple.iohideventsystem")
-    (global-name "com.apple.iphone.axserver-systemwide")
     (global-name "com.apple.frontboard.workspace")
     (global-name "com.apple.frontboard.systemappservices"))
 
 (deny mach-lookup (with send-signal SIGKILL)
     (global-name "com.apple.backboard.hid.services"))
 
+(allow mach-lookup (extension "com.apple.webkit.extension.mach"))
+
 ;; These services have been identified as unused during living-on.
 ;; This list overrides some definitions above and in common.sb.
 ;; FIXME: remove overridden rules once the final list has been
index ddfacb2..693bd70 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
+#include <wtf/ProcessID.h>
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
@@ -46,6 +47,7 @@ public:
     enum class Type {
         ReadOnly,
         ReadWrite,
+        Mach,
         Generic,
     };
 
@@ -101,6 +103,7 @@ public:
     static bool createHandleForReadWriteDirectory(const String& path, Handle&); // Will attempt to create the directory.
     static String createHandleForTemporaryFile(const String& prefix, Type, Handle&);
     static bool createHandleForGenericExtension(const String& extensionClass, Handle&);
+    static bool createHandleForMachLookupByPid(const String& service, ProcessID, Handle&);
     ~SandboxExtension();
 
     bool consume();
index 1f7b961..830f39a 100644 (file)
@@ -40,9 +40,9 @@ namespace WebKit {
 
 class SandboxExtensionImpl {
 public:
-    static std::unique_ptr<SandboxExtensionImpl> create(const char* path, SandboxExtension::Type type)
+    static std::unique_ptr<SandboxExtensionImpl> create(const char* path, SandboxExtension::Type type, Optional<ProcessID> pid = WTF::nullopt)
     {
-        std::unique_ptr<SandboxExtensionImpl> impl { new SandboxExtensionImpl(path, type) };
+        std::unique_ptr<SandboxExtensionImpl> impl { new SandboxExtensionImpl(path, type, pid) };
         if (!impl->m_token)
             return nullptr;
         return impl;
@@ -64,6 +64,10 @@ public:
 #if PLATFORM(IOS_FAMILY_SIMULATOR)
         return !sandbox_check(getpid(), 0, SANDBOX_FILTER_NONE);
 #else
+        if (m_handle == -1) {
+            LOG_ERROR("Could not create a sandbox extension for '%s', errno = %d", m_token, errno);
+            return false;
+        }
         return m_handle;
 #endif
     }
@@ -80,20 +84,22 @@ public:
     }
 
 private:
-    char* sandboxExtensionForType(const char* path, SandboxExtension::Type type)
+    char* sandboxExtensionForType(const char* path, SandboxExtension::Type type, Optional<ProcessID> pid = WTF::nullopt)
     {
         switch (type) {
         case SandboxExtension::Type::ReadOnly:
             return sandbox_extension_issue_file(APP_SANDBOX_READ, path, 0);
         case SandboxExtension::Type::ReadWrite:
             return sandbox_extension_issue_file(APP_SANDBOX_READ_WRITE, path, 0);
+        case SandboxExtension::Type::Mach:
+            return sandbox_extension_issue_mach_to_process_by_pid("com.apple.webkit.extension.mach"_s, path, 0, pid.value());
         case SandboxExtension::Type::Generic:
             return sandbox_extension_issue_generic(path, 0);
         }
     }
 
-    SandboxExtensionImpl(const char* path, SandboxExtension::Type type)
-        : m_token { sandboxExtensionForType(path, type) }
+    SandboxExtensionImpl(const char* path, SandboxExtension::Type type, Optional<ProcessID> pid = WTF::nullopt)
+        : m_token { sandboxExtensionForType(path, type, pid) }
     {
     }
 
@@ -357,6 +363,19 @@ bool SandboxExtension::createHandleForGenericExtension(const String& extensionCl
     return true;
 }
 
+bool SandboxExtension::createHandleForMachLookupByPid(const String& service, ProcessID pid, Handle& handle)
+{
+    ASSERT(!handle.m_sandboxExtension);
+    
+    handle.m_sandboxExtension = SandboxExtensionImpl::create(service.utf8().data(), Type::Mach, pid);
+    if (!handle.m_sandboxExtension) {
+        WTFLogAlways("Could not create a '%s' sandbox extension", service.utf8().data());
+        return false;
+    }
+    
+    return true;
+}
+
 SandboxExtension::SandboxExtension(const Handle& handle)
     : m_sandboxExtension(WTFMove(handle.m_sandboxExtension))
 {
index 4514349..cba1448 100644 (file)
@@ -26,6 +26,7 @@
 #import "config.h"
 #import "WebProcessPool.h"
 
+#import "AccessibilitySupportSPI.h"
 #import "CookieStorageUtilsCF.h"
 #import "LegacyCustomProtocolManagerClient.h"
 #import "NetworkProcessCreationParameters.h"
@@ -447,6 +448,10 @@ void WebProcessPool::registerNotificationObservers()
     }];
 #elif PLATFORM(IOS)
     CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, backlightLevelDidChangeCallback, static_cast<CFStringRef>(UIBacklightLevelChangedNotification), nullptr, CFNotificationSuspensionBehaviorCoalesce);
+    m_accessibilityEnabledObserver = [[NSNotificationCenter defaultCenter] addObserverForName:(__bridge id)kAXSApplicationAccessibilityEnabledNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *) {
+        for (size_t i = 0; i < m_processes.size(); ++i)
+            m_processes[i]->unblockAccessibilityServerIfNeeded();
+    }];
 #endif // !PLATFORM(IOS_FAMILY)
 }
 
@@ -466,6 +471,7 @@ void WebProcessPool::unregisterNotificationObservers()
     [[NSNotificationCenter defaultCenter] removeObserver:m_deactivationObserver.get()];
 #elif PLATFORM(IOS)
     CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, static_cast<CFStringRef>(UIBacklightLevelChangedNotification) , nullptr);
+    [[NSNotificationCenter defaultCenter] removeObserver:m_accessibilityEnabledObserver.get()];
 #endif // !PLATFORM(IOS_FAMILY)
 }
 
index 2bec2fc..54cb757 100644 (file)
@@ -673,6 +673,10 @@ private:
     std::unique_ptr<PerActivityStateCPUUsageSampler> m_perActivityStateCPUUsageSampler;
 #endif
 
+#if PLATFORM(IOS_FAMILY)
+    RetainPtr<NSObject> m_accessibilityEnabledObserver;
+#endif
+
     bool m_shouldUseTestingNetworkSession { false };
 
     bool m_processTerminationEnabled { true };
index 9030df2..55cd873 100644 (file)
@@ -759,6 +759,8 @@ void WebProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Connect
         if (xpc_connection_t xpcConnection = connection()->xpcConnection())
             m_throttler.didConnectToProcess(xpc_connection_get_pid(xpcConnection));
     }
+
+    unblockAccessibilityServerIfNeeded();
 #endif
 }
 
index 258102b..bc3d5f1 100644 (file)
@@ -293,6 +293,10 @@ public:
     void revokeAudioCaptureExtension() { m_mediaCaptureSandboxExtensions &= ~Audio; }
 #endif
 
+#if PLATFORM(IOS_FAMILY)
+    void unblockAccessibilityServerIfNeeded();
+#endif
+
 protected:
     static uint64_t generatePageID();
     WebProcessProxy(WebProcessPool&, WebsiteDataStore&, IsPrewarmed);
@@ -431,6 +435,7 @@ private:
 #if PLATFORM(IOS_FAMILY)
     ForegroundWebProcessToken m_foregroundToken;
     BackgroundWebProcessToken m_backgroundToken;
+    bool m_hasSentMessageToUnblockAccessibilityServer { false };
 #endif
 
     HashMap<String, uint64_t> m_pageURLRetainCountMap;
index 4f92c0c..4388087 100644 (file)
@@ -28,6 +28,7 @@
 
 #if PLATFORM(IOS_FAMILY)
 
+#import "AccessibilitySupportSPI.h"
 #import "WKFullKeyboardAccessWatcher.h"
 #import "WebProcessMessages.h"
 
@@ -42,6 +43,25 @@ bool WebProcessProxy::fullKeyboardAccessEnabled()
 #endif
 }
 
+void WebProcessProxy::unblockAccessibilityServerIfNeeded()
+{
+    if (m_hasSentMessageToUnblockAccessibilityServer)
+        return;
+    if (!_AXSApplicationAccessibilityEnabled())
+        return;
+    if (!processIdentifier())
+        return;
+    if (!canSendMessage())
+        return;
+
+    SandboxExtension::Handle handle;
+    if (!SandboxExtension::createHandleForMachLookupByPid("com.apple.iphone.axserver-systemwide", processIdentifier(), handle))
+        return;
+
+    send(Messages::WebProcess::UnblockAccessibilityServer(handle), 0);
+    m_hasSentMessageToUnblockAccessibilityServer = true;
+}
+
 } // namespace WebKit
 
 #endif // PLATFORM(IOS_FAMILY)
index d40ea81..9fdbc0b 100644 (file)
@@ -1867,4 +1867,12 @@ void WebProcess::clearCurrentModifierStateForTesting()
     PlatformKeyboardEvent::setCurrentModifierState({ });
 }
 
+#if PLATFORM(IOS_FAMILY)
+void WebProcess::unblockAccessibilityServer(const SandboxExtension::Handle& handle)
+{
+    bool ok = SandboxExtension::consumePermanently(handle);
+    ASSERT_UNUSED(ok, ok);
+}
+#endif
+
 } // namespace WebKit
index f17584a..72fe219 100644 (file)
@@ -245,6 +245,8 @@ public:
 
 #if PLATFORM(IOS_FAMILY)
     void accessibilityProcessSuspendedNotification(bool);
+    
+    void unblockAccessibilityServer(const SandboxExtension::Handle&);
 #endif
 
 #if PLATFORM(IOS)
index f011b82..45fed46 100644 (file)
@@ -157,4 +157,8 @@ messages -> WebProcess LegacyReceiver {
 #endif
 
     ClearCurrentModifierStateForTesting()
+
+#if PLATFORM(IOS_FAMILY)
+    UnblockAccessibilityServer(WebKit::SandboxExtension::Handle handle)
+#endif
 }