"""전체 Chrome suite와 실제 자식 Chrome/renderer의 sandbox 인자를 새 증거로 보존한다.""" import json import os from pathlib import Path import subprocess import time EVIDENCE = Path(__file__).resolve().parent ROOT = EVIDENCE.parents[2] environment = dict(os.environ) environment.pop("PLAYWRIGHT_NO_SANDBOX", None) environment["CHROME_PATH"] = "/usr/bin/google-chrome" environment["PLAYWRIGHT_JSON_OUTPUT_NAME"] = str(EVIDENCE / "browser-results.json") command = ["npx", "playwright", "test", "--reporter=line,json", f"--output={EVIDENCE / 'browser-artifacts'}"] observed = {} with (EVIDENCE / "09-browser.log").open("x") as log: process = subprocess.Popen(command, cwd=ROOT, env=environment, stdout=log, stderr=subprocess.STDOUT) while process.poll() is None: parents = {} for path in Path("/proc").glob("[0-9]*"): try: status = dict(line.split(":", 1) for line in (path / "status").read_text().splitlines()) parents[int(path.name)] = (int(status["PPid"]), path, status) except (OSError, ValueError, KeyError): continue children = {process.pid} while True: expanded = children | {pid for pid, (ppid, _, _) in parents.items() if ppid in children} if children == expanded: break children = expanded for pid in children: if pid in observed or pid not in parents: continue _, path, status = parents[pid] try: if (path / "exe").resolve().name != "chrome": continue args = (path / "cmdline").read_bytes().decode().strip("\0").split("\0") observed[pid] = {"pid": pid, "argv": args, "seccomp": status.get("Seccomp", "").strip(), "noNewPrivs": status.get("NoNewPrivs", "").strip()} except OSError: continue time.sleep(0.5) code = process.wait() has_browser = any(not any(arg.startswith("--type=") for arg in row["argv"]) for row in observed.values()) has_renderer = any("--type=renderer" in row["argv"] for row in observed.values()) sandbox = bool(observed) and all("--no-sandbox" not in row["argv"] for row in observed.values()) report = {"command": command, "exitCode": code, "chromiumSandbox": True, "chromeVersion": subprocess.check_output([environment["CHROME_PATH"], "--version"], text=True).strip(), "browserObserved": has_browser, "rendererObserved": has_renderer, "noSandboxFlagAbsent": sandbox, "processes": list(observed.values())} (EVIDENCE / "chrome-sandbox.json").write_text(json.dumps(report, indent=2) + "\n") print(json.dumps({key: value for key, value in report.items() if key != "processes"}, indent=2)) if code or not (has_browser and has_renderer and sandbox): raise SystemExit(code or 1)