https://chromereleases.googleblog.com/2021/07/stable-channel-update-for-desktop_20.html This update includes 35 security fixes. CVEs: CVE-2021-30565 CVE-2021-30566 CVE-2021-30567 CVE-2021-30568 CVE-2021-30569 CVE-2021-30571 CVE-2021-30572 CVE-2021-30573 CVE-2021-30574 CVE-2021-30575 CVE-2021-30576 CVE-2021-30577 CVE-2021-30578 CVE-2021-30579 CVE-2021-30580 CVE-2021-30581 CVE-2021-30582 CVE-2021-30583 CVE-2021-30584 CVE-2021-30585 CVE-2021-30586 CVE-2021-30587 CVE-2021-30588 CVE-2021-30589 Note: This won't be the smoothest update. Chromium seems to be fine but requires gtk3 in $LD_LIBRARY_PATH to find libgtk-3.so.0 (otherwise it crashes during startup) but Google Chrome fails to initialize ("GPU process exited unexpectedly: exit_code=132") and requires "--use-gl=angle --use-angle=swiftshader" for hardware(?) acceleration (which seems to work work fine and performant but SwiftShader should actually use the CPU instead of the GPU).
248 lines
7.6 KiB
Nix
248 lines
7.6 KiB
Nix
{ system ? builtins.currentSystem
|
|
, config ? {}
|
|
, pkgs ? import ../.. { inherit system config; }
|
|
, channelMap ? { # Maps "channels" to packages
|
|
stable = pkgs.chromium;
|
|
beta = pkgs.chromiumBeta;
|
|
dev = pkgs.chromiumDev;
|
|
ungoogled = pkgs.ungoogled-chromium;
|
|
chrome-stable = pkgs.google-chrome;
|
|
chrome-beta = pkgs.google-chrome-beta;
|
|
chrome-dev = pkgs.google-chrome-dev;
|
|
}
|
|
}:
|
|
|
|
with import ../lib/testing-python.nix { inherit system pkgs; };
|
|
with pkgs.lib;
|
|
|
|
mapAttrs (channel: chromiumPkg: makeTest rec {
|
|
name = "chromium-${channel}";
|
|
meta = {
|
|
maintainers = with maintainers; [ aszlig primeos ];
|
|
# https://github.com/NixOS/hydra/issues/591#issuecomment-435125621
|
|
inherit (chromiumPkg.meta) timeout;
|
|
};
|
|
|
|
enableOCR = true;
|
|
|
|
user = "alice";
|
|
|
|
machine.imports = [ ./common/user-account.nix ./common/x11.nix ];
|
|
machine.virtualisation.memorySize = 2047;
|
|
machine.test-support.displayManager.auto.user = user;
|
|
machine.environment = {
|
|
systemPackages = [ chromiumPkg ];
|
|
variables."XAUTHORITY" = "/home/alice/.Xauthority";
|
|
};
|
|
|
|
startupHTML = pkgs.writeText "chromium-startup.html" ''
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Chromium startup notifier</title>
|
|
</head>
|
|
<body onload="javascript:document.title='startup done'">
|
|
<img src="file://${pkgs.fetchurl {
|
|
url = "https://nixos.org/logo/nixos-hex.svg";
|
|
sha256 = "07ymq6nw8kc22m7kzxjxldhiq8gzmc7f45kq2bvhbdm0w5s112s4";
|
|
}}" />
|
|
</body>
|
|
</html>
|
|
'';
|
|
|
|
testScript = let
|
|
xdo = name: text: let
|
|
xdoScript = pkgs.writeText "${name}.xdo" text;
|
|
in "${pkgs.xdotool}/bin/xdotool ${xdoScript}";
|
|
in ''
|
|
import shlex
|
|
import re
|
|
from contextlib import contextmanager
|
|
|
|
|
|
# Run as user alice
|
|
def ru(cmd):
|
|
return "su - ${user} -c " + shlex.quote(cmd)
|
|
|
|
|
|
def launch_browser():
|
|
"""Launches the web browser with the correct options."""
|
|
# Determine the name of the binary:
|
|
pname = "${getName chromiumPkg.name}"
|
|
if pname.find("chromium") != -1:
|
|
binary = "chromium" # Same name for all channels and ungoogled-chromium
|
|
elif pname == "google-chrome":
|
|
binary = "google-chrome-stable"
|
|
elif pname == "google-chrome-dev":
|
|
binary = "google-chrome-unstable"
|
|
else: # For google-chrome-beta and as fallback:
|
|
binary = pname
|
|
# Add optional CLI options:
|
|
options = []
|
|
major_version = "${versions.major (getVersion chromiumPkg.name)}"
|
|
if major_version > "91" and pname.startswith("google-chrome"):
|
|
# To avoid a GPU crash:
|
|
options += ["--use-gl=angle", "--use-angle=swiftshader"]
|
|
options.append("file://${startupHTML}")
|
|
# Launch the process:
|
|
machine.succeed(ru(f'ulimit -c unlimited; {binary} {shlex.join(options)} & disown'))
|
|
if binary.startswith("google-chrome"):
|
|
# Need to click away the first window:
|
|
machine.wait_for_text("Make Google Chrome the default browser")
|
|
machine.screenshot("google_chrome_default_browser_prompt")
|
|
machine.send_key("ret")
|
|
|
|
|
|
def create_new_win():
|
|
"""Creates a new Chromium window."""
|
|
with machine.nested("Creating a new Chromium window"):
|
|
machine.wait_until_succeeds(
|
|
ru(
|
|
"${xdo "create_new_win-select_main_window" ''
|
|
search --onlyvisible --name "startup done"
|
|
windowfocus --sync
|
|
windowactivate --sync
|
|
''}"
|
|
)
|
|
)
|
|
machine.send_key("ctrl-n")
|
|
# Wait until the new window appears:
|
|
machine.wait_until_succeeds(
|
|
ru(
|
|
"${xdo "create_new_win-wait_for_window" ''
|
|
search --onlyvisible --name "New Tab"
|
|
windowfocus --sync
|
|
windowactivate --sync
|
|
''}"
|
|
)
|
|
)
|
|
|
|
|
|
def close_new_tab_win():
|
|
"""Closes the Chromium window with the title "New Tab"."""
|
|
machine.wait_until_succeeds(
|
|
ru(
|
|
"${xdo "close_new_tab_win-select_main_window" ''
|
|
search --onlyvisible --name "New Tab"
|
|
windowfocus --sync
|
|
windowactivate --sync
|
|
''}"
|
|
)
|
|
)
|
|
machine.send_key("ctrl-w")
|
|
# Wait until the closed window disappears:
|
|
machine.wait_until_fails(
|
|
ru(
|
|
"${xdo "close_new_tab_win-wait_for_close" ''
|
|
search --onlyvisible --name "New Tab"
|
|
''}"
|
|
)
|
|
)
|
|
|
|
|
|
@contextmanager
|
|
def test_new_win(description, url, window_name):
|
|
create_new_win()
|
|
machine.wait_for_window("New Tab")
|
|
machine.send_chars(f"{url}\n")
|
|
machine.wait_for_window(window_name)
|
|
machine.screenshot(description)
|
|
machine.succeed(
|
|
ru(
|
|
"${xdo "copy-all" ''
|
|
key --delay 1000 Ctrl+a Ctrl+c
|
|
''}"
|
|
)
|
|
)
|
|
clipboard = machine.succeed(
|
|
ru("${pkgs.xclip}/bin/xclip -o")
|
|
)
|
|
print(f"{description} window content:\n{clipboard}")
|
|
with machine.nested(description):
|
|
yield clipboard
|
|
# Close the newly created window:
|
|
machine.send_key("ctrl-w")
|
|
|
|
|
|
machine.wait_for_x()
|
|
|
|
launch_browser()
|
|
|
|
machine.wait_for_text("startup done")
|
|
machine.wait_until_succeeds(
|
|
ru(
|
|
"${xdo "check-startup" ''
|
|
search --sync --onlyvisible --name "startup done"
|
|
# close first start help popup
|
|
key -delay 1000 Escape
|
|
windowfocus --sync
|
|
windowactivate --sync
|
|
''}"
|
|
)
|
|
)
|
|
|
|
create_new_win()
|
|
# Optional: Wait for the new tab page to fully load before taking the screenshot:
|
|
machine.wait_for_text("Web Store")
|
|
machine.screenshot("empty_windows")
|
|
close_new_tab_win()
|
|
|
|
machine.screenshot("startup_done")
|
|
|
|
with test_new_win("sandbox_info", "chrome://sandbox", "Sandbox Status") as clipboard:
|
|
filters = [
|
|
"layer 1 sandbox.*namespace",
|
|
"pid namespaces.*yes",
|
|
"network namespaces.*yes",
|
|
"seccomp.*sandbox.*yes",
|
|
"you are adequately sandboxed",
|
|
]
|
|
if not all(
|
|
re.search(filter, clipboard, flags=re.DOTALL | re.IGNORECASE)
|
|
for filter in filters
|
|
):
|
|
assert False, f"sandbox not working properly: {clipboard}"
|
|
|
|
machine.sleep(1)
|
|
machine.succeed(
|
|
ru(
|
|
"${xdo "find-window-after-copy" ''
|
|
search --onlyvisible --name "Sandbox Status"
|
|
''}"
|
|
)
|
|
)
|
|
|
|
clipboard = machine.succeed(
|
|
ru(
|
|
"echo void | ${pkgs.xclip}/bin/xclip -i"
|
|
)
|
|
)
|
|
machine.succeed(
|
|
ru(
|
|
"${xdo "copy-sandbox-info" ''
|
|
key --delay 1000 Ctrl+a Ctrl+c
|
|
''}"
|
|
)
|
|
)
|
|
|
|
clipboard = machine.succeed(
|
|
ru("${pkgs.xclip}/bin/xclip -o")
|
|
)
|
|
if not all(
|
|
re.search(filter, clipboard, flags=re.DOTALL | re.IGNORECASE)
|
|
for filter in filters
|
|
):
|
|
assert False, f"copying twice in a row does not work properly: {clipboard}"
|
|
|
|
machine.screenshot("after_copy_from_chromium")
|
|
|
|
|
|
with test_new_win("gpu_info", "chrome://gpu", "chrome://gpu"):
|
|
pass
|
|
|
|
|
|
machine.shutdown()
|
|
'';
|
|
}) channelMap
|