[GTK][WPE] Implement subprocess sandboxing
authormcatanzaro@igalia.com <mcatanzaro@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 Oct 2018 15:02:59 +0000 (15:02 +0000)
committermcatanzaro@igalia.com <mcatanzaro@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 Oct 2018 15:02:59 +0000 (15:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=188568

Patch by Patrick Griffis <pgriffis@igalia.com> on 2018-10-15
Reviewed by Michael Catanzaro.

.:

Add ENABLE_BUBBLEWRAP_SANDBOX option for sandboxing.

* Source/cmake/FindLibseccomp.cmake: Added.
* Source/cmake/OptionsGTK.cmake:
* Source/cmake/WebKitFeatures.cmake:

Source/WebCore:

Link against libseccomp.

* PlatformGTK.cmake:

Source/WebKit:

This implements sandboxing of WebKitWebProcesses.

The sandbox is opt-in at runtime as it is a behavior change.
See webkit_web_context_set_sandbox_enabled() and the
WEBKIT_FORCE_SANDBOX env var for developers.

This is Linux specific using Namespaces, Seccomp, and a DBus proxy service.
This introduces three new dependencies:

- bwrap executable
- libseccomp library
- xdg-dbus-proxy executable

The use of xdg-dbus-proxy will ideally be replaced once upstream DBus
gains the same filtering abilities which is a work in progress.

Currently the sandbox is not completed and there are a few large holes:

- Pulseaudio: The Pipewire project will solve this.
- DRI device access: No immediate solutions planned.
- Webcam device access: Pipewire will also solve this.
- Webprocess network access: Will require GStreamer changes.
- DConf access: Custom proxy planned.
- X11 access: Wayland solves this.

That is not an exhaustive list but are the noteworthy ones. Filesystem access
is still an evolving list as problems are found as is specific DBus name access.

* PlatformGTK.cmake:
* PlatformWPE.cmake:
* SourcesGTK.txt:
* SourcesWPE.txt:
* UIProcess/API/glib/WebKitWebContext.cpp:
(webkit_web_context_set_sandbox_enabled):
(webkit_web_context_get_sandbox_enabled):
* UIProcess/API/gtk/WebKitWebContext.h:
* UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
* UIProcess/API/wpe/WebKitWebContext.h:
* UIProcess/ChildProcessProxy.cpp:
(WebKit::ChildProcessProxy::getLaunchOptions):
* UIProcess/ChildProcessProxy.h:
(WebKit::ChildProcessProxy::platformGetLaunchOptions):
* UIProcess/Launcher/ProcessLauncher.h:
* UIProcess/Launcher/glib/BubblewrapLauncher.cpp: Added.
(WebKit::memfd_create):
(WebKit::argsToFd):
(WebKit::XDGDBusProxyLauncher::setAddress):
(WebKit::XDGDBusProxyLauncher::isRunning const):
(WebKit::XDGDBusProxyLauncher::path const):
(WebKit::XDGDBusProxyLauncher::proxyPath const):
(WebKit::XDGDBusProxyLauncher::setPermissions):
(WebKit::XDGDBusProxyLauncher::launch):
(WebKit::XDGDBusProxyLauncher::childSetupFunc):
(WebKit::XDGDBusProxyLauncher::makeProxyPath):
(WebKit::XDGDBusProxyLauncher::dbusAddressToPath):
(WebKit::bindIfExists):
(WebKit::bindDBusSession):
(WebKit::bindX11):
(WebKit::bindDconf):
(WebKit::bindWayland):
(WebKit::bindPulse):
(WebKit::bindFonts):
(WebKit::bindGtkData):
(WebKit::bindA11y):
(WebKit::bindPathVar):
(WebKit::bindGStreamerData):
(WebKit::bindOpenGL):
(WebKit::bindV4l):
(WebKit::bindSymlinksRealPath):
(WebKit::setupSeccomp):
(WebKit::bubblewrapSpawn):
* UIProcess/Launcher/glib/BubblewrapLauncher.h: Added.
* UIProcess/Launcher/glib/FlatpakLauncher.cpp: Added.
(WebKit::flatpakSpawn):
* UIProcess/Launcher/glib/FlatpakLauncher.h: Added.
* UIProcess/Launcher/glib/ProcessLauncherGLib.cpp:
(WebKit::isInsideFlatpak):
(WebKit::ProcessLauncher::launchProcess):
* UIProcess/Plugins/PluginProcessProxy.cpp:
(WebKit::PluginProcessProxy::getLaunchOptions):
* UIProcess/Plugins/PluginProcessProxy.h:
* UIProcess/Plugins/mac/PluginProcessProxyMac.mm:
(WebKit::PluginProcessProxy::platformGetLaunchOptionsWithAttributes):
* UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp:
(WebKit::PluginProcessProxy::platformGetLaunchOptionsWithAttributes):
* UIProcess/WebProcessPool.h:
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::platformGetLaunchOptions):
* UIProcess/WebProcessProxy.h:
* UIProcess/glib/WebProcessProxyGLib.cpp: Added.
(WebKit::WebProcessProxy::platformGetLaunchOptions):

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

24 files changed:
ChangeLog
Source/WebCore/ChangeLog
Source/WebCore/PlatformGTK.cmake
Source/WebKit/ChangeLog
Source/WebKit/PlatformGTK.cmake
Source/WebKit/PlatformWPE.cmake
Source/WebKit/SourcesGTK.txt
Source/WebKit/SourcesWPE.txt
Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
Source/WebKit/UIProcess/API/gtk/WebKitWebContext.h
Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt
Source/WebKit/UIProcess/API/wpe/WebKitWebContext.h
Source/WebKit/UIProcess/ChildProcessProxy.cpp
Source/WebKit/UIProcess/ChildProcessProxy.h
Source/WebKit/UIProcess/Launcher/glib/ProcessLauncherGLib.cpp
Source/WebKit/UIProcess/Plugins/PluginProcessProxy.cpp
Source/WebKit/UIProcess/Plugins/PluginProcessProxy.h
Source/WebKit/UIProcess/Plugins/mac/PluginProcessProxyMac.mm
Source/WebKit/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp
Source/WebKit/UIProcess/WebProcessPool.h
Source/WebKit/UIProcess/WebProcessProxy.cpp
Source/WebKit/UIProcess/WebProcessProxy.h
Source/cmake/OptionsGTK.cmake
Source/cmake/WebKitFeatures.cmake

index 009d8c9..00f6a53 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2018-10-15  Patrick Griffis  <pgriffis@igalia.com>
+
+        [GTK][WPE] Implement subprocess sandboxing
+        https://bugs.webkit.org/show_bug.cgi?id=188568
+
+        Reviewed by Michael Catanzaro.
+
+        Add ENABLE_BUBBLEWRAP_SANDBOX option for sandboxing.
+
+        * Source/cmake/FindLibseccomp.cmake: Added.
+        * Source/cmake/OptionsGTK.cmake:
+        * Source/cmake/WebKitFeatures.cmake:
+
 2018-10-14  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
 
         [JSC] Remove Option::useAsyncIterator
index 01664a0..1419148 100644 (file)
@@ -1,3 +1,14 @@
+2018-10-15  Patrick Griffis  <pgriffis@igalia.com>
+
+        [GTK][WPE] Implement subprocess sandboxing
+        https://bugs.webkit.org/show_bug.cgi?id=188568
+
+        Reviewed by Michael Catanzaro.
+
+        Link against libseccomp.
+
+        * PlatformGTK.cmake:
+
 2018-10-15  YUHAN WU  <yuhan_wu@apple.com>
 
         Implement error handler of MediaRecorder
index e14ed4a..4eb05cd 100644 (file)
@@ -106,6 +106,7 @@ list(APPEND WebCore_LIBRARIES
     ${GLIB_GMODULE_LIBRARIES}
     ${GLIB_GOBJECT_LIBRARIES}
     ${GLIB_LIBRARIES}
+    ${LIBSECCOMP_LIBRARIES}
     ${LIBSECRET_LIBRARIES}
     ${LIBSOUP_LIBRARIES}
     ${LIBTASN1_LIBRARIES}
@@ -125,6 +126,7 @@ list(APPEND WebCore_SYSTEM_INCLUDE_DIRECTORIES
     ${ENCHANT_INCLUDE_DIRS}
     ${GIO_UNIX_INCLUDE_DIRS}
     ${GLIB_INCLUDE_DIRS}
+    ${LIBSECCOMP_INCLUDE_DIRS}
     ${LIBSECRET_INCLUDE_DIRS}
     ${LIBSOUP_INCLUDE_DIRS}
     ${LIBTASN1_INCLUDE_DIRS}
index 9528972..24402ce 100644 (file)
@@ -1,3 +1,102 @@
+2018-10-15  Patrick Griffis  <pgriffis@igalia.com>
+
+        [GTK][WPE] Implement subprocess sandboxing
+        https://bugs.webkit.org/show_bug.cgi?id=188568
+
+        Reviewed by Michael Catanzaro.
+
+        This implements sandboxing of WebKitWebProcesses.
+
+        The sandbox is opt-in at runtime as it is a behavior change.
+        See webkit_web_context_set_sandbox_enabled() and the
+        WEBKIT_FORCE_SANDBOX env var for developers.
+
+        This is Linux specific using Namespaces, Seccomp, and a DBus proxy service.
+        This introduces three new dependencies:
+
+        - bwrap executable
+        - libseccomp library
+        - xdg-dbus-proxy executable
+
+        The use of xdg-dbus-proxy will ideally be replaced once upstream DBus
+        gains the same filtering abilities which is a work in progress.
+
+        Currently the sandbox is not completed and there are a few large holes:
+
+        - Pulseaudio: The Pipewire project will solve this.
+        - DRI device access: No immediate solutions planned.
+        - Webcam device access: Pipewire will also solve this.
+        - Webprocess network access: Will require GStreamer changes.
+        - DConf access: Custom proxy planned.
+        - X11 access: Wayland solves this.
+
+        That is not an exhaustive list but are the noteworthy ones. Filesystem access
+        is still an evolving list as problems are found as is specific DBus name access.
+
+        * PlatformGTK.cmake:
+        * PlatformWPE.cmake:
+        * SourcesGTK.txt:
+        * SourcesWPE.txt:
+        * UIProcess/API/glib/WebKitWebContext.cpp:
+        (webkit_web_context_set_sandbox_enabled):
+        (webkit_web_context_get_sandbox_enabled):
+        * UIProcess/API/gtk/WebKitWebContext.h:
+        * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
+        * UIProcess/API/wpe/WebKitWebContext.h:
+        * UIProcess/ChildProcessProxy.cpp:
+        (WebKit::ChildProcessProxy::getLaunchOptions):
+        * UIProcess/ChildProcessProxy.h:
+        (WebKit::ChildProcessProxy::platformGetLaunchOptions):
+        * UIProcess/Launcher/ProcessLauncher.h:
+        * UIProcess/Launcher/glib/BubblewrapLauncher.cpp: Added.
+        (WebKit::memfd_create):
+        (WebKit::argsToFd):
+        (WebKit::XDGDBusProxyLauncher::setAddress):
+        (WebKit::XDGDBusProxyLauncher::isRunning const):
+        (WebKit::XDGDBusProxyLauncher::path const):
+        (WebKit::XDGDBusProxyLauncher::proxyPath const):
+        (WebKit::XDGDBusProxyLauncher::setPermissions):
+        (WebKit::XDGDBusProxyLauncher::launch):
+        (WebKit::XDGDBusProxyLauncher::childSetupFunc):
+        (WebKit::XDGDBusProxyLauncher::makeProxyPath):
+        (WebKit::XDGDBusProxyLauncher::dbusAddressToPath):
+        (WebKit::bindIfExists):
+        (WebKit::bindDBusSession):
+        (WebKit::bindX11):
+        (WebKit::bindDconf):
+        (WebKit::bindWayland):
+        (WebKit::bindPulse):
+        (WebKit::bindFonts):
+        (WebKit::bindGtkData):
+        (WebKit::bindA11y):
+        (WebKit::bindPathVar):
+        (WebKit::bindGStreamerData):
+        (WebKit::bindOpenGL):
+        (WebKit::bindV4l):
+        (WebKit::bindSymlinksRealPath):
+        (WebKit::setupSeccomp):
+        (WebKit::bubblewrapSpawn):
+        * UIProcess/Launcher/glib/BubblewrapLauncher.h: Added.
+        * UIProcess/Launcher/glib/FlatpakLauncher.cpp: Added.
+        (WebKit::flatpakSpawn):
+        * UIProcess/Launcher/glib/FlatpakLauncher.h: Added.
+        * UIProcess/Launcher/glib/ProcessLauncherGLib.cpp:
+        (WebKit::isInsideFlatpak):
+        (WebKit::ProcessLauncher::launchProcess):
+        * UIProcess/Plugins/PluginProcessProxy.cpp:
+        (WebKit::PluginProcessProxy::getLaunchOptions):
+        * UIProcess/Plugins/PluginProcessProxy.h:
+        * UIProcess/Plugins/mac/PluginProcessProxyMac.mm:
+        (WebKit::PluginProcessProxy::platformGetLaunchOptionsWithAttributes):
+        * UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp:
+        (WebKit::PluginProcessProxy::platformGetLaunchOptionsWithAttributes):
+        * UIProcess/WebProcessPool.h:
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::platformGetLaunchOptions):
+        * UIProcess/WebProcessProxy.h:
+        * UIProcess/glib/WebProcessProxyGLib.cpp: Added.
+        (WebKit::WebProcessProxy::platformGetLaunchOptions):
+
 2018-10-15  Alex Christensen  <achristensen@webkit.org>
 
         Add a temporarily off by default preference for doing safe browsing checks
index 46cc037..5d8891d 100644 (file)
@@ -19,6 +19,7 @@ add_definitions(-DWEBKIT_DOM_USE_UNSTABLE_API)
 
 add_definitions(-DPKGLIBEXECDIR="${LIBEXEC_INSTALL_DIR}")
 add_definitions(-DLOCALEDIR="${CMAKE_INSTALL_FULL_LOCALEDIR}")
+add_definitions(-DDATADIR="${CMAKE_INSTALL_FULL_DATADIR}")
 add_definitions(-DLIBDIR="${LIB_INSTALL_DIR}")
 
 if (NOT DEVELOPER_MODE AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
@@ -624,6 +625,8 @@ if (ENABLE_PLUGIN_PROCESS_GTK2)
 
         UIProcess/Launcher/ProcessLauncher.cpp
 
+        UIProcess/Launcher/glib/BubblewrapLauncher.cpp
+        UIProcess/Launcher/glib/FlatpakLauncher.cpp
         UIProcess/Launcher/glib/ProcessLauncherGLib.cpp
 
         UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp
index ccfabab..fc83591 100644 (file)
@@ -16,6 +16,7 @@ add_definitions(-DWEBKIT2_COMPILATION)
 
 add_definitions(-DPKGLIBDIR="${LIB_INSTALL_DIR}/wpe-webkit-${WPE_API_VERSION}")
 add_definitions(-DPKGLIBEXECDIR="${LIBEXEC_INSTALL_DIR}")
+add_definitions(-DDATADIR="${CMAKE_INSTALL_FULL_DATADIR}")
 add_definitions(-DLOCALEDIR="${CMAKE_INSTALL_FULL_LOCALEDIR}")
 
 if (NOT DEVELOPER_MODE AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
index fc5f55f..09c8903 100644 (file)
@@ -203,6 +203,8 @@ UIProcess/Automation/cairo/WebAutomationSessionCairo.cpp
 UIProcess/Automation/gtk/WebAutomationSessionGtk.cpp
 
 UIProcess/Launcher/glib/ProcessLauncherGLib.cpp @no-unify
+UIProcess/Launcher/glib/BubblewrapLauncher.cpp @no-unify
+UIProcess/Launcher/glib/FlatpakLauncher.cpp @no-unify
 
 UIProcess/Network/CustomProtocols/LegacyCustomProtocolManagerProxy.cpp
 
@@ -220,6 +222,7 @@ UIProcess/WebsiteData/unix/WebsiteDataStoreUnix.cpp
 UIProcess/cairo/BackingStoreCairo.cpp @no-unify
 
 UIProcess/glib/RemoteInspectorClient.cpp
+UIProcess/glib/WebProcessProxyGLib.cpp
 
 UIProcess/gstreamer/InstallMissingMediaPluginsPermissionRequest.cpp
 UIProcess/gstreamer/WebPageProxyGStreamer.cpp
index 9655ae2..3afd156 100644 (file)
@@ -177,7 +177,11 @@ UIProcess/Automation/cairo/WebAutomationSessionCairo.cpp
 
 UIProcess/Automation/wpe/WebAutomationSessionWPE.cpp
 
+UIProcess/glib/WebProcessProxyGLib.cpp
+
 UIProcess/Launcher/glib/ProcessLauncherGLib.cpp
+UIProcess/Launcher/glib/BubblewrapLauncher.cpp
+UIProcess/Launcher/glib/FlatpakLauncher.cpp
 
 UIProcess/Network/CustomProtocols/LegacyCustomProtocolManagerProxy.cpp
 
index 3f52625..32ce06c 100644 (file)
@@ -1148,6 +1148,51 @@ void webkit_web_context_register_uri_scheme(WebKitWebContext* context, const cha
 }
 
 /**
+ * webkit_web_context_set_sandbox_enabled:
+ * @context: a #WebKitWebContext
+ * @enabled: if %TRUE enable sandboxing
+ *
+ * Set whether WebKit subprocesses will be sandboxed, limiting access to the system.
+ *
+ * This method **must be called before any web process has been created**,
+ * as early as possible in your application. Calling it later is a fatal error.
+ *
+ * This is only implemented on Linux and is a no-op otherwise.
+ *
+ * If you read from `$XDG_CONFIG_HOME/g_get_prgname()` or `$XDG_CACHE_HOME/g_get_prgname()`
+ * in your WebProcess you must ensure it exists before subprocesses are created.
+ * This behavior may change in the future.
+ *
+ * Since: 2.24
+ */
+void webkit_web_context_set_sandbox_enabled(WebKitWebContext* context, gboolean enabled)
+{
+    g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context));
+
+    if (context->priv->processPool->processes().size())
+        g_error("Sandboxing cannot be changed after subprocesses were spawned.");
+
+    context->priv->processPool->setSandboxEnabled(enabled);
+}
+
+/**
+ * webkit_web_context_get_sandbox_enabled:
+ * @context: a #WebKitWebContext
+ *
+ * Get whether sandboxing is currently enabled.
+ *
+ * Returns: %TRUE if sandboxing is enabled, or %FALSE otherwise.
+ *
+ * Since: 2.24
+ */
+gboolean webkit_web_context_get_sandbox_enabled(WebKitWebContext* context)
+{
+    g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), FALSE);
+
+    return context->priv->processPool->sandboxEnabled();
+}
+
+/**
  * webkit_web_context_get_spell_checking_enabled:
  * @context: a #WebKitWebContext
  *
index 3149a32..bbdeac9 100644 (file)
@@ -247,6 +247,13 @@ webkit_web_context_register_uri_scheme              (WebKitWebContext
                                                      gpointer                       user_data,
                                                      GDestroyNotify                 user_data_destroy_func);
 
+WEBKIT_API void
+webkit_web_context_set_sandbox_enabled              (WebKitWebContext              *context,
+                                                     gboolean                       enabled);
+
+WEBKIT_API gboolean
+webkit_web_context_get_sandbox_enabled              (WebKitWebContext              *context);
+
 WEBKIT_API gboolean
 webkit_web_context_get_spell_checking_enabled       (WebKitWebContext              *context);
 
index 874c43a..b724c0d 100644 (file)
@@ -51,6 +51,8 @@ webkit_web_context_get_security_manager
 webkit_web_context_set_additional_plugins_directory
 webkit_web_context_get_plugins
 webkit_web_context_get_plugins_finish
+webkit_web_context_get_sandbox_enabled
+webkit_web_context_set_sandbox_enabled
 webkit_web_context_get_spell_checking_enabled
 webkit_web_context_set_spell_checking_enabled
 webkit_web_context_get_spell_checking_languages
index 8cf646f..0eb8f36 100644 (file)
@@ -297,6 +297,13 @@ WEBKIT_API WebKitProcessModel
 webkit_web_context_get_process_model                (WebKitWebContext              *context);
 
 WEBKIT_API void
+webkit_web_context_set_sandbox_enabled              (WebKitWebContext              *context,
+                                                     gboolean                       enabled);
+
+WEBKIT_API gboolean
+webkit_web_context_get_sandbox_enabled              (WebKitWebContext              *context);
+
+WEBKIT_API void
 webkit_web_context_initialize_notification_permissions
                                                     (WebKitWebContext              *context,
                                                      GList                         *allowed_origins,
index 9e8eff4..2dd86d8 100644 (file)
@@ -80,6 +80,8 @@ void ChildProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchO
     if (processCmdPrefix && *processCmdPrefix)
         launchOptions.processCmdPrefix = String::fromUTF8(processCmdPrefix);
 #endif // ENABLE(DEVELOPER_MODE) && (PLATFORM(GTK) || PLATFORM(WPE))
+
+    platformGetLaunchOptions(launchOptions);
 }
 
 void ChildProcessProxy::connect()
index c891279..192f3da 100644 (file)
@@ -93,6 +93,7 @@ protected:
     bool dispatchSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&);
     
     virtual void getLaunchOptions(ProcessLauncher::LaunchOptions&);
+    virtual void platformGetLaunchOptions(ProcessLauncher::LaunchOptions&) { };
 
 private:
     virtual void connectionWillOpen(IPC::Connection&);
index 81cd003..7ae40b8 100644 (file)
@@ -27,7 +27,9 @@
 #include "config.h"
 #include "ProcessLauncher.h"
 
+#include "BubblewrapLauncher.h"
 #include "Connection.h"
+#include "FlatpakLauncher.h"
 #include "ProcessExecutablePath.h"
 #include <WebCore/FileSystem.h>
 #include <errno.h>
@@ -53,10 +55,27 @@ static void childSetupFunction(gpointer userData)
     close(socket);
 }
 
-void ProcessLauncher::launchProcess()
+#if OS(LINUX)
+static bool isInsideFlatpak()
 {
-    GPid pid = 0;
+    static int ret = -1;
+    if (ret != -1)
+        return ret;
+
+    GUniquePtr<GKeyFile> infoFile(g_key_file_new());
+    if (!g_key_file_load_from_file(infoFile.get(), "/.flatpak-info", G_KEY_FILE_NONE, nullptr)) {
+        ret = false;
+        return ret;
+    }
 
+    // If we are in a `flatpak build` session we cannot launch ourselves since we aren't installed.
+    ret = !g_key_file_get_boolean(infoFile.get(), "Instance", "build", nullptr);
+    return ret;
+}
+#endif
+
+void ProcessLauncher::launchProcess()
+{
     IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection(IPC::Connection::ConnectionOptions::SetCloexecOnServer);
 
     String executablePath;
@@ -140,17 +159,40 @@ void ProcessLauncher::launchProcess()
 #endif
     argv[i++] = nullptr;
 
+    GRefPtr<GSubprocessLauncher> launcher = adoptGRef(g_subprocess_launcher_new(G_SUBPROCESS_FLAGS_INHERIT_FDS));
+    g_subprocess_launcher_set_child_setup(launcher.get(), childSetupFunction, GINT_TO_POINTER(socketPair.server), nullptr);
+    g_subprocess_launcher_take_fd(launcher.get(), socketPair.client, socketPair.client);
+
     GUniqueOutPtr<GError> error;
-    if (!g_spawn_async(nullptr, argv, nullptr, G_SPAWN_LEAVE_DESCRIPTORS_OPEN, childSetupFunction, GINT_TO_POINTER(socketPair.server), &pid, &error.outPtr()))
+    GRefPtr<GSubprocess> process;
+#if OS(LINUX)
+    const char* sandboxEnv = g_getenv("WEBKIT_FORCE_SANDBOX");
+    bool sandboxEnabled = m_launchOptions.extraInitializationData.get("enable-sandbox") == "true";
+
+    if (sandboxEnv)
+        sandboxEnabled = !strcmp(sandboxEnv, "1");
+
+    if (sandboxEnabled && isInsideFlatpak())
+        process = flatpakSpawn(launcher.get(), m_launchOptions, argv, &error.outPtr());
+#if ENABLE(BUBBLEWRAP_SANDBOX)
+    else if (sandboxEnabled)
+        process = bubblewrapSpawn(launcher.get(), m_launchOptions, argv, &error.outPtr());
+#endif
+    else
+#endif
+        process = adoptGRef(g_subprocess_launcher_spawnv(launcher.get(), argv, &error.outPtr()));
+
+    if (!process.get())
         g_error("Unable to fork a new child process: %s", error->message);
 
+    const char* processIdStr = g_subprocess_get_identifier(process.get());
+    m_processIdentifier = g_ascii_strtoll(processIdStr, nullptr, 0);
+    RELEASE_ASSERT(m_processIdentifier);
+
     // Don't expose the parent socket to potential future children.
     if (!setCloseOnExec(socketPair.client))
         RELEASE_ASSERT_NOT_REACHED();
 
-    close(socketPair.client);
-    m_processIdentifier = pid;
-
     // We've finished launching the process, message back to the main run loop.
     RunLoop::main().dispatch([protectedThis = makeRef(*this), this, serverSocket = socketPair.server] {
         didFinishLaunchingProcess(m_processIdentifier, serverSocket);
index eded9c7..e29769c 100644 (file)
@@ -87,7 +87,7 @@ PluginProcessProxy::~PluginProcessProxy()
 
 void PluginProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions)
 {
-    platformGetLaunchOptions(launchOptions, m_pluginProcessAttributes);
+    platformGetLaunchOptionsWithAttributes(launchOptions, m_pluginProcessAttributes);
     ChildProcessProxy::getLaunchOptions(launchOptions);
 }
 
index 386af00..c7e94a8 100644 (file)
@@ -96,7 +96,7 @@ private:
     PluginProcessProxy(PluginProcessManager*, const PluginProcessAttributes&, uint64_t pluginProcessToken);
 
     void getLaunchOptions(ProcessLauncher::LaunchOptions&) override;
-    void platformGetLaunchOptions(ProcessLauncher::LaunchOptions&, const PluginProcessAttributes&);
+    void platformGetLaunchOptionsWithAttributes(ProcessLauncher::LaunchOptions&, const PluginProcessAttributes&);
     void processWillShutDown(IPC::Connection&) override;
 
     void pluginProcessCrashedOrFailedToLaunch();
index d90f0a9..87b5b8c 100644 (file)
@@ -60,7 +60,7 @@ namespace WebKit {
 using namespace WebCore;
 
     
-void PluginProcessProxy::platformGetLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions, const PluginProcessAttributes& pluginProcessAttributes)
+void PluginProcessProxy::platformGetLaunchOptionsWithAttributes(ProcessLauncher::LaunchOptions& launchOptions, const PluginProcessAttributes& pluginProcessAttributes)
 {
     if (pluginProcessAttributes.moduleInfo.pluginArchitecture == CPU_TYPE_X86)
         launchOptions.processType = ProcessLauncher::ProcessType::Plugin32;
index f9ef2ca..f896121 100644 (file)
@@ -50,7 +50,7 @@
 namespace WebKit {
 using namespace WebCore;
 
-void PluginProcessProxy::platformGetLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions, const PluginProcessAttributes& pluginProcessAttributes)
+void PluginProcessProxy::platformGetLaunchOptionsWithAttributes(ProcessLauncher::LaunchOptions& launchOptions, const PluginProcessAttributes& pluginProcessAttributes)
 {
     launchOptions.processType = ProcessLauncher::ProcessType::Plugin64;
 
index ff8eb15..682ac2f 100644 (file)
@@ -455,6 +455,11 @@ public:
 
     void sendDisplayConfigurationChangedMessageForTesting();
 
+#if PLATFORM(GTK) || PLATFORM(WPE)
+    void setSandboxEnabled(bool enabled) { m_sandboxEnabled = enabled; };
+    bool sandboxEnabled() const { return m_sandboxEnabled; };
+#endif
+
 private:
     void platformInitialize();
 
@@ -702,6 +707,10 @@ private:
     HashMap<String, RefPtr<WebProcessProxy>> m_swappedProcessesPerRegistrableDomain;
 
     HashMap<String, std::unique_ptr<WebCore::PrewarmInformation>> m_prewarmInformationPerRegistrableDomain;
+
+#if PLATFORM(GTK) || PLATFORM(WPE)
+    bool m_sandboxEnabled { false };
+#endif
 };
 
 template<typename T>
index c9947db..fd998e1 100644 (file)
@@ -206,6 +206,12 @@ void WebProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOpt
     }
 }
 
+#if !PLATFORM(GTK) && !PLATFORM(WPE)
+void WebProcessProxy::platformGetLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions)
+{
+}
+#endif
+
 void WebProcessProxy::connectionWillOpen(IPC::Connection& connection)
 {
     ASSERT(this->connection() == &connection);
index 33274df..d0e7ecb 100644 (file)
@@ -239,6 +239,7 @@ protected:
 
     // ChildProcessProxy
     void getLaunchOptions(ProcessLauncher::LaunchOptions&) override;
+    void platformGetLaunchOptions(ProcessLauncher::LaunchOptions&) override;
     void connectionWillOpen(IPC::Connection&) override;
     void processWillShutDown(IPC::Connection&) override;
 
index 63d0590..29ab498 100644 (file)
@@ -118,6 +118,12 @@ else ()
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_RESOURCE_USAGE PRIVATE OFF)
 endif ()
 
+if (CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT EXISTS "/.flatpak-info")
+    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_BUBBLEWRAP_SANDBOX PUBLIC ON)
+else ()
+    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_BUBBLEWRAP_SANDBOX PRIVATE OFF)
+endif ()
+
 # Public options shared with other WebKit ports. Do not add any options here
 # without approval from a GTK+ reviewer. There must be strong reason to support
 # changing the value of the option.
@@ -201,6 +207,38 @@ if (ENABLE_ACCELERATED_2D_CANVAS)
     endif ()
 endif ()
 
+if (ENABLE_BUBBLEWRAP_SANDBOX)
+    find_program(BWRAP_EXECUTABLE bwrap)
+    if (NOT BWRAP_EXECUTABLE)
+        message(FATAL_ERROR "bwrap executable is needed for ENABLE_BUBBLEWRAP_SANDBOX")
+    endif ()
+    add_definitions(-DBWRAP_EXECUTABLE="${BWRAP_EXECUTABLE}")
+
+    execute_process(
+        COMMAND "${BWRAP_EXECUTABLE}" --version
+        RESULT_VARIABLE BWRAP_RET
+        OUTPUT_VARIABLE BWRAP_OUTPUT
+    )
+    if (BWRAP_RET)
+        message(FATAL_ERROR "Failed to run ${BWRAP_EXECUTABLE}")
+    endif ()
+    string(REGEX MATCH "([0-9]+.[0-9]+.[0-9]+)" BWRAP_VERSION "${BWRAP_OUTPUT}")
+    if (NOT "${BWRAP_VERSION}" VERSION_GREATER_EQUAL "0.3.1")
+        message(FATAL_ERROR "bwrap must be >= 0.3.1 but ${BWRAP_VERSION} found")
+    endif ()
+
+    find_package(Libseccomp)
+    if (NOT LIBSECCOMP_FOUND)
+        message(FATAL_ERROR "libseccomp is needed for ENABLE_BUBBLEWRAP_SANDBOX")
+    endif ()
+
+    find_program(DBUS_PROXY_EXECUTABLE xdg-dbus-proxy)
+    if (NOT DBUS_PROXY_EXECUTABLE)
+        message(FATAL_ERROR "xdg-dbus-proxy not found and is needed for ENABLE_BUBBLEWRAP_SANDBOX")
+    endif ()
+    add_definitions(-DDBUS_PROXY_EXECUTABLE="${DBUS_PROXY_EXECUTABLE}")
+endif ()
+
 if (USE_LIBSECRET)
     find_package(Libsecret)
     if (NOT LIBSECRET_FOUND)
index 011e123..d343026 100644 (file)
@@ -88,6 +88,7 @@ macro(WEBKIT_OPTION_BEGIN)
     WEBKIT_OPTION_DEFINE(ENABLE_ASYNC_SCROLLING "Enable asynchronouse scrolling" PRIVATE OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_ATTACHMENT_ELEMENT "Toggle attachment element support" PRIVATE OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_AVF_CAPTIONS "Toggle AVFoundation caption support" PRIVATE OFF)
+    WEBKIT_OPTION_DEFINE(ENABLE_BUBBLEWRAP_SANDBOX "Toggle bubblewrap sandboxing support" PRIVATE OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_CACHE_PARTITIONING "Toggle cache partitioning support" PRIVATE OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_CHANNEL_MESSAGING "Toggle MessageChannel and MessagePort support" PRIVATE ON)
     WEBKIT_OPTION_DEFINE(ENABLE_CONTENT_FILTERING "Toggle content filtering support" PRIVATE OFF)