summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2022-03-03 21:16:04 +0100
committerFlorian Bruhin <me@the-compiler.org>2022-03-03 21:16:04 +0100
commit8fe1de2fdcdf03cd3f460e6abc5eb3a09fdbaa43 (patch)
tree4376a447a56d2fcd4f8601564b99c04467fd80f9
parent38acd8f44ad5f4046e846653014739294239c15c (diff)
downloadqutebrowser-8fe1de2fdcdf03cd3f460e6abc5eb3a09fdbaa43.tar.gz
qutebrowser-8fe1de2fdcdf03cd3f460e6abc5eb3a09fdbaa43.zip
Add qt.chromium.sandboxing setting and sandboxing test
-rw-r--r--doc/changelog.asciidoc1
-rw-r--r--doc/help/settings.asciidoc25
-rw-r--r--qutebrowser/config/configdata.yml30
-rw-r--r--qutebrowser/config/qtargs.py5
-rw-r--r--tests/end2end/test_invocations.py45
-rw-r--r--tests/unit/config/test_qtargs.py22
6 files changed, 128 insertions, 0 deletions
diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc
index 3c462ad4b..9df2ce00c 100644
--- a/doc/changelog.asciidoc
+++ b/doc/changelog.asciidoc
@@ -60,6 +60,7 @@ Added
which shows relative tab numbers.
- New `input.mode_override` option which allows overriding the current mode
based on the new URL when navigating or switching tabs.
+- New `qt.chromium.sandboxing` setting which allows to disable Chromium's sandboxing (mainly intended for development and testing)
Fixed
~~~~~
diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc
index 8623bd15e..2e51ecc7f 100644
--- a/doc/help/settings.asciidoc
+++ b/doc/help/settings.asciidoc
@@ -289,6 +289,7 @@
|<<qt.args,qt.args>>|Additional arguments to pass to Qt, without leading `--`.
|<<qt.chromium.low_end_device_mode,qt.chromium.low_end_device_mode>>|When to use Chromium's low-end device mode.
|<<qt.chromium.process_model,qt.chromium.process_model>>|Which Chromium process model to use.
+|<<qt.chromium.sandboxing,qt.chromium.sandboxing>>|What sandboxing mechanisms in Chromium to use.
|<<qt.environ,qt.environ>>|Additional environment variables to set.
|<<qt.force_platform,qt.force_platform>>|Force a Qt platform to use.
|<<qt.force_platformtheme,qt.force_platformtheme>>|Force a Qt platformtheme to use.
@@ -3814,6 +3815,30 @@ Valid values:
Default: +pass:[process-per-site-instance]+
+[[qt.chromium.sandboxing]]
+=== qt.chromium.sandboxing
+What sandboxing mechanisms in Chromium to use.
+Chromium has various sandboxing layers, which should be enabled for normal browser usage. Mainly for testing and development, it's possible to disable individual sandboxing layers via this setting.
+Open `chrome://sandbox` to see the current sandbox status.
+Changing this setting is only recommended if you know what you're doing, as it **disables one of Chromium's security layers**. To avoid sandboxing being accidentally disabled persistently, this setting can only be set via `config.py`, not via `:set`.
+See the Chromium documentation for more details: - Linux: https://chromium.googlesource.com/chromium/src/+/HEAD/docs/linux/sandboxing.md - Windows: https://chromium.googlesource.com/chromium/src/+/HEAD/docs/design/sandbox.md - FAQ (Windows-centric): https://chromium.googlesource.com/chromium/src/+/HEAD/docs/design/sandbox_faq.md
+
+This setting requires a restart.
+
+This setting can only be set in config.py.
+
+This setting is only available with the QtWebEngine backend.
+
+Type: <<types,String>>
+
+Valid values:
+
+ * +enable-all+: Enable all available sandboxing mechanisms.
+ * +disable-seccomp-bpf+: Disable the Seccomp BPF filter sandbox (Linux only).
+ * +disable-all+: Disable all sandboxing (**not recommended!**).
+
+Default: +pass:[enable-all]+
+
[[qt.environ]]
=== qt.environ
Additional environment variables to set.
diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml
index 5d3099e79..e4caf05af 100644
--- a/qutebrowser/config/configdata.yml
+++ b/qutebrowser/config/configdata.yml
@@ -290,6 +290,36 @@ qt.chromium.low_end_device_mode:
This improves the RAM usage of renderer processes, at the expense of
performance.
+qt.chromium.sandboxing:
+ type:
+ name: String
+ valid_values:
+ - enable-all: Enable all available sandboxing mechanisms.
+ - disable-seccomp-bpf: Disable the Seccomp BPF filter sandbox (Linux only).
+ - disable-all: Disable all sandboxing (**not recommended!**).
+ default: enable-all
+ backend: QtWebEngine
+ restart: true
+ no_autoconfig: true # due to it being dangerous
+ desc: >-
+ What sandboxing mechanisms in Chromium to use.
+
+ Chromium has various sandboxing layers, which should be enabled for normal
+ browser usage. Mainly for testing and development, it's possible to disable
+ individual sandboxing layers via this setting.
+
+ Open `chrome://sandbox` to see the current sandbox status.
+
+ Changing this setting is only recommended if you know what you're doing, as
+ it **disables one of Chromium's security layers**. To avoid sandboxing being
+ accidentally disabled persistently, this setting can only be set via
+ `config.py`, not via `:set`.
+
+ See the Chromium documentation for more details:
+ - Linux: https://chromium.googlesource.com/chromium/src/+/HEAD/docs/linux/sandboxing.md
+ - Windows: https://chromium.googlesource.com/chromium/src/+/HEAD/docs/design/sandbox.md
+ - FAQ (Windows-centric): https://chromium.googlesource.com/chromium/src/+/HEAD/docs/design/sandbox_faq.md
+
qt.highdpi:
type: Bool
default: false
diff --git a/qutebrowser/config/qtargs.py b/qutebrowser/config/qtargs.py
index 165bdba5f..9e7f2620d 100644
--- a/qutebrowser/config/qtargs.py
+++ b/qutebrowser/config/qtargs.py
@@ -338,6 +338,11 @@ def _qtwebengine_settings_args(versions: version.WebEngineVersions) -> Iterator[
True: '--force-prefers-reduced-motion',
False: None,
},
+ 'qt.chromium.sandboxing': {
+ 'enable-all': None,
+ 'disable-seccomp-bpf': '--disable-seccomp-filter-sandbox',
+ 'disable-all': '--no-sandbox',
+ }
}
qt_514_ver = utils.VersionNumber(5, 14)
diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py
index b860feed0..0e252b741 100644
--- a/tests/end2end/test_invocations.py
+++ b/tests/end2end/test_invocations.py
@@ -826,3 +826,48 @@ def test_json_logging_without_debug(request, quteproc_new, runtime_tmpdir):
quteproc_new.exit_expected = True
quteproc_new.start(args, env={'XDG_RUNTIME_DIR': str(runtime_tmpdir)})
assert not quteproc_new.is_running()
+
+
+@pytest.mark.qtwebkit_skip
+@pytest.mark.parametrize('sandboxing, has_namespaces, has_seccomp, has_yama, expected_result', [
+ ('enable-all', True, True, True, "You are adequately sandboxed."),
+ ('disable-seccomp-bpf', True, False, True, "You are NOT adequately sandboxed."),
+ ('disable-all', False, False, False, "You are NOT adequately sandboxed."),
+])
+def test_sandboxing(
+ request, quteproc_new, sandboxing,
+ has_namespaces, has_seccomp, has_yama, expected_result,
+):
+ args = _base_args(request.config) + [
+ '--temp-basedir',
+ '-s', 'qt.chromium.sandboxing', sandboxing,
+ ]
+ quteproc_new.start(args)
+
+ quteproc_new.open_url('chrome://sandbox')
+ text = quteproc_new.get_content()
+ print(text)
+ header, *lines, empty, result = text.split("\n")
+
+ assert header == "Sandbox Status"
+ assert not empty
+
+ status = dict(line.split("\t") for line in lines)
+
+ bpf_text = "Seccomp-BPF sandbox"
+ yama_text = "Ptrace Protection with Yama LSM"
+ expected_status = {
+ "Layer 1 Sandbox": "Namespace" if has_namespaces else "None",
+
+ "PID namespaces": "Yes" if has_namespaces else "No",
+ "Network namespaces": "Yes" if has_namespaces else "No",
+
+ bpf_text: "Yes" if has_seccomp else "No",
+ f"{bpf_text} supports TSYNC": "Yes" if has_seccomp else "No",
+
+ f"{yama_text} (Broker)": "Yes" if has_yama else "No",
+ f"{yama_text} (Non-broker)": "No",
+ }
+
+ assert status == expected_status
+ assert result == expected_result
diff --git a/tests/unit/config/test_qtargs.py b/tests/unit/config/test_qtargs.py
index bc4029b3d..076ff6e3c 100644
--- a/tests/unit/config/test_qtargs.py
+++ b/tests/unit/config/test_qtargs.py
@@ -277,6 +277,28 @@ class TestWebEngineArgs:
else:
assert arg in args
+ @pytest.mark.parametrize('sandboxing, arg', [
+ ('enable-all', None),
+ ('disable-seccomp-bpf', '--disable-seccomp-filter-sandbox'),
+ ('disable-all', '--no-sandbox'),
+ ])
+ def test_sandboxing(self, config_stub, parser, sandboxing, arg):
+ config_stub.val.qt.chromium.sandboxing = sandboxing
+ parsed = parser.parse_args([])
+ args = qtargs.qt_args(parsed)
+
+ remaining_flags = {
+ '--no-sandbox',
+ '--disable-seccomp-filter-sandbox',
+ }
+ if arg is not None:
+ remaining_flags.remove(arg)
+
+ if arg is not None:
+ assert arg in args
+
+ assert not set(args) & remaining_flags
+
@pytest.mark.parametrize('qt_version, referer, arg', [
# 'always' -> no arguments
('5.15.0', 'always', None),