Add the possibility to run unsandboxed plug-ins
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 Jul 2018 00:26:03 +0000 (00:26 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 Jul 2018 00:26:03 +0000 (00:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=187310
<rdar://problem/41798808>

Reviewed by Alexey Proskuryakov.

Source/WebCore:

Add a runtime flag to enforce plugin sandboxing.
Covered by manual testing.

* page/RuntimeEnabledFeatures.h:
(WebCore::RuntimeEnabledFeatures::setSandboxPlugInEnabled):
(WebCore::RuntimeEnabledFeatures::sandboxPlugInEnabled const):

Source/WebKit:

Add a utility method to know which plug-ins are allowed to run unsandboxed.
For such plug-ins, we skip the sandboxing done when starting the plug-in process.

* PluginProcess/mac/PluginProcessMac.mm:
(WebKit::PluginProcess::initializeSandbox):
* Shared/WebPreferences.yaml:
* UIProcess/Plugins/PluginInfoStore.cpp:
(WebKit::PluginInfoStore::shouldRunPluginUnsandboxed):
* UIProcess/Plugins/PluginInfoStore.h:
* UIProcess/Plugins/mac/PluginInfoStoreMac.mm:
(WebKit::PluginInfoStore::shouldRunPluginUnsandboxed):
(WebKit::PluginInfoStore::shouldUsePlugin):

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

Source/WebCore/ChangeLog
Source/WebCore/page/RuntimeEnabledFeatures.h
Source/WebKit/ChangeLog
Source/WebKit/PluginProcess/mac/PluginProcessMac.mm
Source/WebKit/Shared/WebPreferences.yaml
Source/WebKit/UIProcess/Plugins/PluginInfoStore.cpp
Source/WebKit/UIProcess/Plugins/PluginInfoStore.h
Source/WebKit/UIProcess/Plugins/mac/PluginInfoStoreMac.mm

index 24cd295..8d249fc 100644 (file)
@@ -1,3 +1,18 @@
+2018-07-09  Youenn Fablet  <youenn@apple.com>
+
+        Add the possibility to run unsandboxed plug-ins
+        https://bugs.webkit.org/show_bug.cgi?id=187310
+        <rdar://problem/41798808>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Add a runtime flag to enforce plugin sandboxing.
+        Covered by manual testing.
+
+        * page/RuntimeEnabledFeatures.h:
+        (WebCore::RuntimeEnabledFeatures::setSandboxPlugInEnabled):
+        (WebCore::RuntimeEnabledFeatures::sandboxPlugInEnabled const):
+
 2018-07-09  Dean Jackson  <dino@apple.com>
 
         Remove fullscreen-auto-hide-delay
index 61ea8ed..4c7f660 100644 (file)
@@ -265,6 +265,9 @@ public:
     void setServerTimingEnabled(bool isEnabled) { m_isServerTimingEnabled = isEnabled; }
     bool serverTimingEnabled() const { return m_isServerTimingEnabled; }
 
+    void setExperimentalPlugInSandboxProfilesEnabled(bool isEnabled) { m_experimentalPlugInSandboxProfilesEnabled = isEnabled; }
+    bool experimentalPlugInSandboxProfilesEnabled() const { return m_experimentalPlugInSandboxProfilesEnabled; }
+
     void setDisabledAdaptationsMetaTagEnabled(bool isEnabled) { m_disabledAdaptationsMetaTagEnabled = isEnabled; }
     bool disabledAdaptationsMetaTagEnabled() const { return m_disabledAdaptationsMetaTagEnabled; }
 
@@ -406,6 +409,7 @@ private:
     bool m_isWebGLCompressedTextureASTCSupportEnabled { false };
     bool m_promptForStorageAccessAPIEnabled { false };
     bool m_isServerTimingEnabled { false };
+    bool m_experimentalPlugInSandboxProfilesEnabled { false };
     bool m_disabledAdaptationsMetaTagEnabled { false };
 
 #if USE(SYSTEM_PREVIEW)
index 903fcaa..5bbcf93 100644 (file)
@@ -1,3 +1,24 @@
+2018-07-09  Youenn Fablet  <youenn@apple.com>
+
+        Add the possibility to run unsandboxed plug-ins
+        https://bugs.webkit.org/show_bug.cgi?id=187310
+        <rdar://problem/41798808>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Add a utility method to know which plug-ins are allowed to run unsandboxed.
+        For such plug-ins, we skip the sandboxing done when starting the plug-in process.
+
+        * PluginProcess/mac/PluginProcessMac.mm:
+        (WebKit::PluginProcess::initializeSandbox):
+        * Shared/WebPreferences.yaml:
+        * UIProcess/Plugins/PluginInfoStore.cpp:
+        (WebKit::PluginInfoStore::shouldRunPluginUnsandboxed):
+        * UIProcess/Plugins/PluginInfoStore.h:
+        * UIProcess/Plugins/mac/PluginInfoStoreMac.mm:
+        (WebKit::PluginInfoStore::shouldRunPluginUnsandboxed):
+        (WebKit::PluginInfoStore::shouldUsePlugin):
+
 2018-07-09  Dean Jackson  <dino@apple.com>
 
         Remove fullscreen-auto-hide-delay
index 638b3e6..9bb621b 100644 (file)
@@ -31,6 +31,7 @@
 
 #import "ArgumentCoders.h"
 #import "NetscapePlugin.h"
+#import "PluginInfoStore.h"
 #import "PluginProcessCreationParameters.h"
 #import "PluginProcessProxyMessages.h"
 #import "PluginProcessShim.h"
@@ -633,6 +634,21 @@ void PluginProcess::initializeSandbox(const ChildProcessInitializationParameters
         return;
     }
 
+    char cacheDirectory[PATH_MAX];
+    if (!confstr(_CS_DARWIN_USER_CACHE_DIR, cacheDirectory, sizeof(cacheDirectory))) {
+        WTFLogAlways("PluginProcess: couldn't retrieve system cache directory path: %d\n", errno);
+        exit(EX_OSERR);
+    }
+
+    m_nsurlCacheDirectory = [[[NSFileManager defaultManager] stringWithFileSystemRepresentation:cacheDirectory length:strlen(cacheDirectory)] stringByAppendingPathComponent:[[NSBundle mainBundle] bundleIdentifier]];
+    if (![[NSFileManager defaultManager] createDirectoryAtURL:[NSURL fileURLWithPath:m_nsurlCacheDirectory isDirectory:YES] withIntermediateDirectories:YES attributes:nil error:nil]) {
+        WTFLogAlways("PluginProcess: couldn't create NSURL cache directory '%s'\n", cacheDirectory);
+        exit(EX_OSERR);
+    }
+
+    if (PluginInfoStore::shouldAllowPluginToRunUnsandboxed(m_pluginBundleIdentifier))
+        return;
+
     bool parentIsSandboxed = parameters.connectionIdentifier.xpcConnection && connectedProcessIsSandboxed(parameters.connectionIdentifier.xpcConnection.get());
 
     if (parameters.extraInitializationData.get("disable-sandbox") == "1") {
@@ -660,18 +676,6 @@ void PluginProcess::initializeSandbox(const ChildProcessInitializationParameters
         exit(EX_OSERR);
     }
 
-    char cacheDirectory[PATH_MAX];
-    if (!confstr(_CS_DARWIN_USER_CACHE_DIR, cacheDirectory, sizeof(cacheDirectory))) {
-        WTFLogAlways("PluginProcess: couldn't retrieve system cache directory path: %d\n", errno);
-        exit(EX_OSERR);
-    }
-
-    m_nsurlCacheDirectory = [[[NSFileManager defaultManager] stringWithFileSystemRepresentation:cacheDirectory length:strlen(temporaryDirectory)] stringByAppendingPathComponent:[[NSBundle mainBundle] bundleIdentifier]];
-    if (![[NSFileManager defaultManager] createDirectoryAtURL:[NSURL fileURLWithPath:m_nsurlCacheDirectory isDirectory:YES] withIntermediateDirectories:YES attributes:nil error:nil]) {
-        WTFLogAlways("PluginProcess: couldn't create NSURL cache directory '%s'\n", temporaryDirectory);
-        exit(EX_OSERR);
-    }
-
     if (strlcpy(temporaryDirectory, [[[[NSFileManager defaultManager] stringWithFileSystemRepresentation:temporaryDirectory length:strlen(temporaryDirectory)] stringByAppendingPathComponent:@"WebKitPlugin-XXXXXX"] fileSystemRepresentation], sizeof(temporaryDirectory)) >= sizeof(temporaryDirectory)
         || !mkdtemp(temporaryDirectory)) {
         WTFLogAlways("PluginProcess: couldn't create private temporary directory '%s'\n", temporaryDirectory);
index 2533317..9a57e74 100644 (file)
@@ -1257,6 +1257,15 @@ ServerTimingEnabled:
   webcoreBinding: RuntimeEnabledFeatures
   webcoreName: serverTimingEnabled
 
+ExperimentalPlugInSandboxProfilesEnabled:
+  type: bool
+  defaultValue: false
+  humanReadableName: "Sandbox Plug-Ins"
+  humanReadableDescription: "Enable Plug-In sandboxing"
+  category: debug
+  webcoreBinding: RuntimeEnabledFeatures
+  webcoreName: experimentalPlugInSandboxProfilesEnabled
+
 FullScreenEnabled:
   type: bool
   defaultValue: DEFAULT_ENABLE_FULLSCREEN_API
index 6ebb6ca..b946315 100644 (file)
@@ -160,6 +160,12 @@ static inline String pathExtension(const URL& url)
 
 #if !PLATFORM(COCOA)
 
+bool PluginInfoStore::shouldAllowPluginToRunUnsandboxed(const String& pluginBundleIdentifier)
+{
+    UNUSED_PARAM(pluginBundleIdentifier);
+    return false;
+}
+
 PluginModuleLoadPolicy PluginInfoStore::defaultLoadPolicyForPlugin(const PluginModuleInfo&)
 {
     return PluginModuleLoadNormally;
index 8b2f04e..6e9eefc 100644 (file)
@@ -68,6 +68,8 @@ public:
     void addSupportedPlugin(String&& matchingDomain, String&& identifier, HashSet<String>&& mimeTypes, HashSet<String> extensions);
     void clearSupportedPlugins() { m_supportedPlugins = std::nullopt; }
 
+    static bool shouldAllowPluginToRunUnsandboxed(const String& pluginBundleIdentifier);
+
 private:
     PluginModuleInfo findPluginForMIMEType(const String& mimeType, WebCore::PluginData::AllowedPluginTypes) const;
     PluginModuleInfo findPluginForExtension(const String& extension, String& mimeType, WebCore::PluginData::AllowedPluginTypes) const;
index c82c209..654073e 100644 (file)
@@ -32,6 +32,7 @@
 #import "NetscapePluginModule.h"
 #import "SandboxUtilities.h"
 #import <WebCore/PluginBlacklist.h>
+#import <WebCore/RuntimeEnabledFeatures.h>
 #import <pwd.h>
 #import <wtf/HashSet.h>
 #import <wtf/RetainPtr.h>
@@ -83,6 +84,16 @@ static bool shouldBlockPlugin(const PluginModuleInfo& plugin)
     return loadPolicy == PluginModuleBlockedForSecurity || loadPolicy == PluginModuleBlockedForCompatibility;
 }
 
+bool PluginInfoStore::shouldAllowPluginToRunUnsandboxed(const String& pluginBundleIdentifier)
+{
+    if (RuntimeEnabledFeatures::sharedFeatures().experimentalPlugInSandboxProfilesEnabled())
+        return false;
+
+    return pluginBundleIdentifier == "com.cisco.webex.plugin.gpc64"_s
+        || pluginBundleIdentifier == "com.google.googletalkbrowserplugin"_s
+        || pluginBundleIdentifier == "com.google.o1dbrowserplugin"_s;
+}
+
 bool PluginInfoStore::shouldUsePlugin(Vector<PluginModuleInfo>& alreadyLoadedPlugins, const PluginModuleInfo& plugin)
 {
     for (size_t i = 0; i < alreadyLoadedPlugins.size(); ++i) {
@@ -104,7 +115,7 @@ bool PluginInfoStore::shouldUsePlugin(Vector<PluginModuleInfo>& alreadyLoadedPlu
         return false;
     }
 
-    if (currentProcessIsSandboxed() && !plugin.hasSandboxProfile) {
+    if (currentProcessIsSandboxed() && !plugin.hasSandboxProfile && !shouldAllowPluginToRunUnsandboxed(plugin.bundleIdentifier)) {
         LOG(Plugins, "Ignoring unsandboxed plug-in %s", plugin.bundleIdentifier.utf8().data());
         return false;
     }