58 lines
2.9 KiB
Plaintext
58 lines
2.9 KiB
Plaintext
"""전체 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)
|