55 lines
3.1 KiB
Python
55 lines
3.1 KiB
Python
"""보존된 Chrome 원문 argv와 Playwright JSON으로 sandbox/전체 실행 결과를 요약한다."""
|
|||
|
|
import json
|
||
|
|
from pathlib import Path
|
||
|
|
import re
|
||
|
|
|
||
|
|
EVIDENCE = Path(__file__).resolve().parent
|
||
|
|
|
||
|
|
|
||
|
|
def sandbox_summary(processes):
|
||
|
|
"""이 환경의 /proc는 전체 명령을 argv[0] 하나로도 반환한다. 정확한 flag 경계를 검사한다."""
|
||
|
|
def flag(row, value):
|
||
|
|
return bool(re.search(r"(?:^|\s)" + re.escape(value) + r"(?:\s|$)", " ".join(row["argv"])))
|
||
|
|
|
||
|
|
renderers = [row for row in processes if flag(row, "--type=renderer")]
|
||
|
|
browser = [row for row in processes if not re.search(r"(?:^|\s)--type=", " ".join(row["argv"]))]
|
||
|
|
return {
|
||
|
|
"browserObserved": bool(browser),
|
||
|
|
"rendererObserved": bool(renderers),
|
||
|
|
"browserProcessCount": len(browser),
|
||
|
|
"rendererProcessCount": len(renderers),
|
||
|
|
"noSandboxFlagAbsent": bool(processes) and all(not flag(row, "--no-sandbox") for row in processes),
|
||
|
|
"rendererSeccompEnabled": bool(renderers) and all(row["seccomp"] == "2" for row in renderers),
|
||
|
|
"rendererNoNewPrivs": bool(renderers) and all(row["noNewPrivs"] == "1" for row in renderers),
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
original = json.loads((EVIDENCE / "chrome-process-observations.json").read_text())
|
||
|
|
sandbox = sandbox_summary(original["processes"])
|
||
|
|
# 1요소 argv와 NUL로 분리된 argv 모두 flag를 검출하며 --no-zygote-sandbox와 혼동하지 않는다.
|
||
|
|
for args in (["chrome", "--type=renderer", "--no-sandbox"], ["chrome --type=renderer --no-sandbox"]):
|
||
|
|
negative = sandbox_summary([{"argv": args, "seccomp": "0", "noNewPrivs": "0"}])
|
||
|
|
if negative["noSandboxFlagAbsent"] or not negative["rendererObserved"]:
|
||
|
|
raise ValueError("Sandbox flag parser regression")
|
||
|
|
if not all(sandbox[key] for key in ("browserObserved", "rendererObserved", "noSandboxFlagAbsent",
|
||
|
|
"rendererSeccompEnabled", "rendererNoNewPrivs")):
|
||
|
|
raise ValueError(sandbox)
|
||
|
|
corrected = {
|
||
|
|
"source": "chrome-process-observations.json",
|
||
|
|
"correction": "Original parser used argv list membership; this /proc capture contains the whole command in argv[0]. Raw process observations are unchanged. Corrected flag-boundary parsing detects browser and sandboxed renderers.",
|
||
|
|
"playwrightExitCode": original["exitCode"],
|
||
|
|
"initialCollectorExitCode": 1,
|
||
|
|
"chromeVersion": original["chromeVersion"],
|
||
|
|
"chromiumSandbox": original["chromiumSandbox"],
|
||
|
|
**sandbox,
|
||
|
|
}
|
||
|
|
(EVIDENCE / "chrome-sandbox.json").write_text(json.dumps(corrected, indent=2) + "\n")
|
||
|
|
results = json.loads((EVIDENCE / "browser-results.json").read_text())
|
||
|
|
stats = results["stats"]
|
||
|
|
if stats["expected"] != 36 or any(stats[key] for key in ("unexpected", "skipped", "flaky")) or results["errors"]:
|
||
|
|
raise ValueError("Full browser suite did not pass cleanly")
|
||
|
|
summary = {"stats": stats, "errors": results["errors"], "sandbox": corrected}
|
||
|
|
(EVIDENCE / "browser-summary.json").write_text(json.dumps(summary, indent=2) + "\n")
|
||
|
|
print(json.dumps(summary, indent=2))
|