diff --git a/deploy/tests/test_example_units.py b/deploy/tests/test_example_units.py index dac8b31..a1b2338 100644 --- a/deploy/tests/test_example_units.py +++ b/deploy/tests/test_example_units.py @@ -306,3 +306,25 @@ def test_server_hardening_dropin_present_with_directives(): for line in text.splitlines(): bare = line.split("#", 1)[0].strip() assert bare != "ProcSubset=pid", "ProcSubset=pid must not be active in the server drop-in" + + +def test_hardening_dropins_agree_on_syscall_architectures(): + # Both units fork-exec a 32-bit binary on critical paths: the web + # service runs the install job (steamcmd_linux), the server unit runs + # srcds_linux. Either drop-in without `x86` in SystemCallArchitectures + # SIGSYS-kills its child on first syscall (bash exit 159). They must + # agree, and both must include x86 — caught the hard way on + # 2026-05-15 when web had `native` only and the install job died. + import re + + pat = re.compile(r"^SystemCallArchitectures=(.+)$", re.MULTILINE) + web_arch = pat.search(WEB_HARDENING_DROPIN.read_text()).group(1).strip() + srv_arch = pat.search(SERVER_HARDENING_DROPIN.read_text()).group(1).strip() + assert web_arch == srv_arch, ( + f"hardening drop-ins disagree on SystemCallArchitectures: " + f"web={web_arch!r} server={srv_arch!r}. Both must include `x86`." + ) + assert "x86" in web_arch.split(), ( + f"SystemCallArchitectures missing x86: {web_arch!r}. Required for " + "steamcmd_linux (install job) and srcds_linux." + )