From f88349413ce4dbd046603c3b74851328af0fec02 Mon Sep 17 00:00:00 2001 From: Sebastien Tardif Date: Sun, 16 Aug 2026 16:19:09 -0700 Subject: [PATCH] fix(eval): stop creating world-writable trial directories Native-eval start chmod'd agent, verifier, and artifact log dirs to 0o777, so another user on the same host could plant or rewrite trial logs. Create those dirs as 0o755 instead. Signed-off-by: Sebastien Tardif --- scripts/native_eval/runtime.py | 7 +++++-- tests/test_native_eval_runner.py | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/scripts/native_eval/runtime.py b/scripts/native_eval/runtime.py index f26f693..505cdb2 100644 --- a/scripts/native_eval/runtime.py +++ b/scripts/native_eval/runtime.py @@ -103,14 +103,17 @@ def verifier_dir(self) -> Path: def artifacts_dir(self) -> Path: return self.trial_dir / "artifacts" - async def start(self) -> CommandResult: + def prepare_trial_dirs(self) -> None: for path in ( self.agent_dir, self.verifier_dir, self.artifacts_dir / "logs" / "artifacts", ): path.mkdir(parents=True, exist_ok=True) - path.chmod(0o777) + path.chmod(0o755) + + async def start(self) -> CommandResult: + self.prepare_trial_dirs() started_at = utc_now() try: diff --git a/tests/test_native_eval_runner.py b/tests/test_native_eval_runner.py index 6aef78f..15e4d02 100644 --- a/tests/test_native_eval_runner.py +++ b/tests/test_native_eval_runner.py @@ -2,6 +2,7 @@ import asyncio import json +import stat import subprocess import sys import tarfile @@ -1260,6 +1261,26 @@ async def fake_capture(command: list[str]) -> str: ) +def test_prepare_trial_dirs_are_owner_writable_only(tmp_path: Path) -> None: + environment = DockerTaskEnvironment( + task=object(), # type: ignore[arg-type] + trial_dir=tmp_path, + container_name="trial", + project_name="trial", + toolchain_root=tmp_path, + ) + + environment.prepare_trial_dirs() + + for path in ( + environment.agent_dir, + environment.verifier_dir, + environment.artifacts_dir / "logs" / "artifacts", + ): + assert path.is_dir() + assert stat.S_IMODE(path.stat().st_mode) == 0o755 + + def test_claude_code_selects_canonical_model_explicitly() -> None: run = RunSpec( run_label="claude-code-test",