From 7444179a2331860ff72d4c675ec832d40d8e343c Mon Sep 17 00:00:00 2001 From: toofar Date: Sat, 18 Nov 2023 18:01:52 +1300 Subject: Update parsing of sandbox page on windows in tests In the linux branch when it was doing: header, *lines, empty, result = text.split("\n") assert not empty It was complaining that "empty" was "}", because the windows sandbox page has JSON at the bottom now. The whole things looks to have changed completely. I'm actually surprised it was working before, why would it have been saying seccomp was enabled on windows? Anyway, I did the debug-dump-text --plain that quteproc is doing in a VM and tested this with sandboxing off an on. No idea how stable that will be! ref: https://github.com/qutebrowser/qutebrowser/issues/7989 --- tests/end2end/test_invocations.py | 84 +++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 16 deletions(-) diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py index af81781f6..72e08af96 100644 --- a/tests/end2end/test_invocations.py +++ b/tests/end2end/test_invocations.py @@ -15,6 +15,7 @@ import re import json import platform from contextlib import nullcontext as does_not_raise +from unittest.mock import ANY import pytest from qutebrowser.qt.core import QProcess, QPoint @@ -885,27 +886,78 @@ def test_sandboxing( bpf_text = "Seccomp-BPF sandbox" yama_text = "Ptrace Protection with Yama LSM" - header, *lines, empty, result = text.split("\n") - assert not empty + if not utils.is_windows: + header, *lines, empty, result = text.split("\n") + assert not empty - expected_status = { - "Layer 1 Sandbox": "Namespace" if has_namespaces else "None", + 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", + "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", + 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)": "Yes" if has_yama_non_broker else "No", - } - - assert header == "Sandbox Status" - assert result == expected_result + f"{yama_text} (Broker)": "Yes" if has_yama else "No", + f"{yama_text} (Non-broker)": "Yes" if has_yama_non_broker else "No", + } - status = dict(line.split("\t") for line in lines) - assert status == expected_status + assert header == "Sandbox Status" + assert result == expected_result + + status = dict(line.split("\t") for line in lines) + assert status == expected_status + + else: # utils.is_windows + # The sandbox page on Windows if different that Linux and macOS. It's + # a lot more complex. There is a table up top with lots of columns and + # a row per tab and helper process then a json object per row down + # below with even more detail (which we ignore). + # https://www.chromium.org/Home/chromium-security/articles/chrome-sandbox-diagnostics-for-windows/ + + # We're not getting full coverage of the table and there doesn't seem + # to be a simple summary like for linux. The "Sandbox" and "Lockdown" + # column are probably the key ones. + # We are looking at all the rows in the table for the sake of + # completeness, but I expect there will always be just one row with a + # renderer process in it for this test. If other helper processes pop + # up we might want to exclude them. + lines = text.split("\n") + assert lines.pop(0) == "Sandbox Status" + header = lines.pop(0).split("\t") + rows = [] + current_line = lines.pop(0) + while current_line.strip(): + if lines[0].startswith("\t"): + # Continuation line. Not sure how to 100% identify them + # but new rows should start with a process ID. + current_line += lines.pop(0) + continue + + columns = current_line.split("\t") + assert len(header) == len(columns) + rows.append(dict(zip(header, columns))) + current_line = lines.pop(0) + + assert rows + + # I'm using has_namespaces as a proxy for "should be sandboxed" here, + # which is a bit lazy but its either that or match on the text + # "sandboxing" arg. The seccomp-bpf arg does nothing on windows, so + # we only have the off and on states. + for row in rows: + assert row == { + "Process": ANY, + "Type": "Renderer", + "Name": "", + "Sandbox": "Renderer" if has_namespaces else "Not Sandboxed", + "Lockdown": "Lockdown" if has_namespaces else "", + "Integrity": ANY if has_namespaces else "", + "Mitigations": ANY if has_namespaces else "", + "Component Filter": ANY if has_namespaces else "", + "Lowbox/AppContainer": "", + } @pytest.mark.not_frozen -- cgit v1.2.3-54-g00ecf