summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-10-31 11:28:09 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-12-19 14:05:40 +0100
commit79d4cf6e8eb569ec039c33e407fab787cc1a687f (patch)
treeb62d60ef2a8d1ed5662cdc38a68505ac018f1bf4 /src
parent16651238b839b0e85c8a225657b6650c6005b176 (diff)
Enable Windows sandbox
Enable sandboxing on Windows. Enable heterogeneous sandbox symbol resolution and statically link the sandboxing code into the helper process. This means we have two copies of the sandboxing code, one statically linked in the executable and one in the shared library. Since they are not exported they don't conflict, but we need to take to initialize the right version in the helper process binary, and pass its sandbox interface to shared library using it. For sandbox debug output, we also need to initialize the second copy of the commandlineparser and logging system. Fixes: QTBUG-51170 Change-Id: I8f503c8d6b40674465f32772ef906817dad2b449 Reviewed-by: Kirill Burtsev <kirill.burtsev@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/buildtools/config/windows.pri3
-rw-r--r--src/core/process_main.cpp17
-rw-r--r--src/core/process_main.h2
-rw-r--r--src/core/qtwebengine.gni4
-rw-r--r--src/core/qtwebengine_sources.gni6
-rw-r--r--src/core/web_engine_context.cpp23
-rw-r--r--src/core/web_engine_context.h13
-rw-r--r--src/process/main.cpp8
-rw-r--r--src/process/process.pro21
-rw-r--r--src/process/support_win.cpp49
10 files changed, 131 insertions, 15 deletions
diff --git a/src/buildtools/config/windows.pri b/src/buildtools/config/windows.pri
index b11396a0c..5d7b7e1f2 100644
--- a/src/buildtools/config/windows.pri
+++ b/src/buildtools/config/windows.pri
@@ -6,7 +6,8 @@ gn_args += \
ninja_use_custom_environment_files=false \
is_multi_dll_chrome=false \
win_linker_timing=true \
- com_init_check_hook_disabled=true
+ com_init_check_hook_disabled=true \
+ heterogeneous_executables=true
clang_cl {
clang_full_path = $$system_path($$which($${QMAKE_CXX}))
diff --git a/src/core/process_main.cpp b/src/core/process_main.cpp
index d661d3b90..ade0f6e99 100644
--- a/src/core/process_main.cpp
+++ b/src/core/process_main.cpp
@@ -49,20 +49,27 @@
#include "sandbox/mac/seatbelt_exec.h"
#endif
-namespace QtWebEngine {
+namespace QtWebEngineCore {
+
+#if defined(OS_WIN)
+extern sandbox::SandboxInterfaceInfo *staticSandboxInterfaceInfo(sandbox::SandboxInterfaceInfo *info = nullptr);
+#endif
/*! \internal */
int processMain(int argc, const char **argv)
{
- QtWebEngineCore::ContentMainDelegateQt delegate;
+ ContentMainDelegateQt delegate;
content::ContentMainParams params(&delegate);
#if defined(OS_WIN)
HINSTANCE instance_handle = NULL;
+ params.sandbox_info = staticSandboxInterfaceInfo();
sandbox::SandboxInterfaceInfo sandbox_info = {0};
- content::InitializeSandboxInfo(&sandbox_info);
+ if (!params.sandbox_info) {
+ content::InitializeSandboxInfo(&sandbox_info);
+ params.sandbox_info = &sandbox_info;
+ }
params.instance = instance_handle;
- params.sandbox_info = &sandbox_info;
#else
params.argc = argc;
params.argv = argv;
@@ -78,4 +85,4 @@ int processMain(int argc, const char **argv)
return content::ContentMain(params);
}
-} // namespace
+} // namespace QtWebEngineCore
diff --git a/src/core/process_main.h b/src/core/process_main.h
index 00c029d9f..fed2f3064 100644
--- a/src/core/process_main.h
+++ b/src/core/process_main.h
@@ -50,7 +50,7 @@
#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
-namespace QtWebEngine {
+namespace QtWebEngineCore {
Q_WEBENGINECORE_PRIVATE_EXPORT int processMain(int argc, const char **argv);
diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni
index cd8514352..9106e4d56 100644
--- a/src/core/qtwebengine.gni
+++ b/src/core/qtwebengine.gni
@@ -65,6 +65,10 @@ if (enable_extensions) {
]
}
+if (is_win) {
+ data_deps = [ ":qtwebengine_sandbox_win" ]
+}
+
defines = [
"CHROMIUM_VERSION=\"" + chromium_version[0] + "\""
]
diff --git a/src/core/qtwebengine_sources.gni b/src/core/qtwebengine_sources.gni
index b4a6b3b83..011a143b5 100644
--- a/src/core/qtwebengine_sources.gni
+++ b/src/core/qtwebengine_sources.gni
@@ -179,3 +179,9 @@ source_set("qtwebengine_sources") {
}
}
+if (is_win) {
+ shared_library("qtwebengine_sandbox_win") {
+ create_pri_file = true
+ public_deps = [ "//sandbox/win:sandbox" ]
+ }
+}
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index a4ceb3a97..69769bdf1 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -182,6 +182,18 @@ void dummyGetPluginCallback(const std::vector<content::WebPluginInfo>&)
namespace QtWebEngineCore {
+#if defined(Q_OS_WIN)
+sandbox::SandboxInterfaceInfo *staticSandboxInterfaceInfo(sandbox::SandboxInterfaceInfo *info)
+{
+ static sandbox::SandboxInterfaceInfo *g_info = nullptr;
+ if (info) {
+ Q_ASSERT(g_info == nullptr);
+ g_info = info;
+ }
+ return g_info;
+}
+#endif
+
extern std::unique_ptr<base::MessagePump> messagePumpFactory();
bool usingSoftwareDynamicGL()
@@ -455,9 +467,7 @@ WebEngineContext::WebEngineContext()
// Enable sandboxing on OS X and Linux (Desktop / Embedded) by default.
bool disable_sandbox = qEnvironmentVariableIsSet(kDisableSandboxEnv);
if (!disable_sandbox) {
-#if defined(Q_OS_WIN)
- parsedCommandLine->AppendSwitch(service_manager::switches::kNoSandbox);
-#elif defined(Q_OS_LINUX)
+#if defined(Q_OS_LINUX)
parsedCommandLine->AppendSwitch(service_manager::switches::kDisableSetuidSandbox);
#endif
} else {
@@ -656,9 +666,12 @@ WebEngineContext::WebEngineContext()
content::ContentMainParams contentMainParams(m_mainDelegate.get());
#if defined(OS_WIN)
+ contentMainParams.sandbox_info = staticSandboxInterfaceInfo();
sandbox::SandboxInterfaceInfo sandbox_info = {0};
- content::InitializeSandboxInfo(&sandbox_info);
- contentMainParams.sandbox_info = &sandbox_info;
+ if (!contentMainParams.sandbox_info) {
+ content::InitializeSandboxInfo(&sandbox_info);
+ contentMainParams.sandbox_info = &sandbox_info;
+ }
#endif
m_contentRunner->Initialize(contentMainParams);
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index 5892017c5..ac0536596 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -40,9 +40,12 @@
#ifndef WEB_ENGINE_CONTEXT_H
#define WEB_ENGINE_CONTEXT_H
+#include "qtwebenginecoreglobal_p.h"
+
#include "build_config_qt.h"
#include "base/memory/ref_counted.h"
#include "base/values.h"
+
#include <QVector>
namespace base {
@@ -75,6 +78,12 @@ class PrintJobManager;
}
#endif
+#ifdef Q_OS_WIN
+namespace sandbox {
+struct SandboxInterfaceInfo;
+}
+#endif
+
QT_FORWARD_DECLARE_CLASS(QObject)
namespace QtWebEngineCore {
@@ -86,6 +95,10 @@ class ProfileAdapter;
bool usingSoftwareDynamicGL();
+#ifdef Q_OS_WIN
+Q_WEBENGINECORE_PRIVATE_EXPORT sandbox::SandboxInterfaceInfo *staticSandboxInterfaceInfo(sandbox::SandboxInterfaceInfo *info = nullptr);
+#endif
+
typedef std::tuple<bool, QString, QString> ProxyAuthentication;
class WebEngineContext : public base::RefCounted<WebEngineContext> {
diff --git a/src/process/main.cpp b/src/process/main.cpp
index ef653e109..53596d0ee 100644
--- a/src/process/main.cpp
+++ b/src/process/main.cpp
@@ -89,13 +89,17 @@ struct tm* localtime64_r_proxy(const time_t* timep, struct tm* result)
#endif // defined(OS_LINUX)
#ifdef Q_OS_WIN
+namespace QtWebEngineProcess {
void initDpiAwareness();
+void initializeStaticCopy(int argc, const char **argv);
+} // namespace
#endif // defined(Q_OS_WIN)
int main(int argc, const char **argv)
{
#ifdef Q_OS_WIN
- initDpiAwareness();
+ QtWebEngineProcess::initializeStaticCopy(argc, argv);
+ QtWebEngineProcess::initDpiAwareness();
#endif
// Chromium on Linux manipulates argv to set a process title
@@ -123,6 +127,6 @@ int main(int argc, const char **argv)
QCoreApplication qtApplication(argc, argv_.get());
- return QtWebEngine::processMain(argc, argv);
+ return QtWebEngineCore::processMain(argc, argv);
}
diff --git a/src/process/process.pro b/src/process/process.pro
index 0bdc9dd93..ecde20d04 100644
--- a/src/process/process.pro
+++ b/src/process/process.pro
@@ -9,7 +9,28 @@ INCLUDEPATH += ../core
SOURCES = main.cpp
+# On windows we need to statically link to the windows sandbox code
win32 {
+ # The Chromium headers we include are not clean
+ CONFIG -= warnings_are_errors
+
+ # Look for linking information produced by GN
+ linking_pri = $$OUT_PWD/../core/$$getConfigDir()/qtwebengine_sandbox_win.pri
+
+ !include($$linking_pri) {
+ error("Could not find the linking information that gn should have generated.")
+ }
+ isEmpty(NINJA_OBJECTS): error("//sandbox/win:sandbox linking changed, update process.pro")
+ isEmpty(NINJA_ARCHIVES): error("//sandbox/win:sandbox linking changed, update process.pro")
+
+ LIBS_PRIVATE += $$NINJA_LIB_DIRS $$NINJA_LIBS $$NINJA_ARCHIVES $$NINJA_OBJECTS
+ QMAKE_LFLAGS += $$NINJA_LFLAGS
+ POST_TARGETDEPS += $$eval($$NINJA_TARGETDEPS)
+
+ CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$$getChromiumSrcDir()
+ INCLUDEPATH += $$CHROMIUM_SRC_DIR \
+ $$OUT_PWD/../core/$$getConfigDir()/gen
+
SOURCES += \
support_win.cpp
diff --git a/src/process/support_win.cpp b/src/process/support_win.cpp
index 3d0ef37bf..4fe69b7a9 100644
--- a/src/process/support_win.cpp
+++ b/src/process/support_win.cpp
@@ -41,7 +41,13 @@
#include <qoperatingsystemversion.h>
#include <qsysinfo.h>
#include <qt_windows.h>
-#include <Tlhelp32.h>
+#include <TlHelp32.h>
+#include "../3rdparty/chromium/sandbox/win/src/process_mitigations.h"
+#include "../3rdparty/chromium/sandbox/win/src/sandbox_factory.h"
+
+#ifndef NDEBUG
+#include "../3rdparty/chromium/base/command_line.h"
+#endif
class User32DLL {
public:
@@ -134,6 +140,45 @@ static DWORD getParentProcessId()
return parentPid;
}
+namespace QtWebEngineCore {
+extern __declspec(dllimport) sandbox::SandboxInterfaceInfo *staticSandboxInterfaceInfo(sandbox::SandboxInterfaceInfo *info = nullptr);
+}
+
+namespace QtWebEngineProcess {
+
+// A duplicate of the function by same name in startup_helper_win.cc
+static void InitializeSandboxInfo(sandbox::SandboxInterfaceInfo *info)
+{
+ info->broker_services = sandbox::SandboxFactory::GetBrokerServices();
+ if (!info->broker_services) {
+ info->target_services = sandbox::SandboxFactory::GetTargetServices();
+ } else {
+ // Ensure the proper mitigations are enforced for the browser process.
+ sandbox::ApplyProcessMitigationsToCurrentProcess(
+ sandbox::MITIGATION_DEP | sandbox::MITIGATION_DEP_NO_ATL_THUNK |
+ sandbox::MITIGATION_HARDEN_TOKEN_IL_POLICY);
+ // Note: these mitigations are "post-startup". Some mitigations that need
+ // to be enabled sooner (e.g. MITIGATION_EXTENSION_POINT_DISABLE) are done
+ // so in Chrome_ELF.
+ }
+}
+
+// Initializes the staticlib copy of //base and //sandbox used for Windows sandboxing
+void initializeStaticCopy(int argc, const char **argv)
+{
+#ifndef NDEBUG
+ // Initialize //base for debugging
+ base::CommandLine::Init(argc, argv);
+ logging::LoggingSettings settings;
+ settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
+ logging::InitLogging(settings);
+#endif
+ sandbox::SandboxInterfaceInfo *info = new sandbox::SandboxInterfaceInfo();
+ memset(info, 0, sizeof(sandbox::SandboxInterfaceInfo));
+ InitializeSandboxInfo(info);
+ QtWebEngineCore::staticSandboxInterfaceInfo(info);
+}
+
void initDpiAwareness()
{
ShcoreDLL shcore;
@@ -157,3 +202,5 @@ void initDpiAwareness()
user32.setProcessDPIAware();
}
}
+
+} // namespace QtWebEngineProcess