Repository navigation
fix(docker): harden the docker-* task container like repos containers #248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
890089a
41355f8
0ea7173
c690563
b1340c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| ### Changed | ||
|
|
||
| - **`docker-*` task containers are hardened like `repos` containers** — the | ||
| task container starts with `--init`, `--cap-drop ALL`, `--security-opt no-new-privileges` | ||
| and `--pids-limit 32768`, and gets back only `CHOWN`, `DAC_OVERRIDE` and `FOWNER` | ||
| (the harness's own root steps on the agent's tree) and `SETUID` and `SETGID` | ||
| (task scripts that drop privileges, such as apt's `_apt` sandbox). A setuid binary | ||
| in a task image can no longer raise its privileges. Every other capability Docker | ||
| grants by default is dropped, so a solve or verifier step that needs one now fails: | ||
| killing another user's process (`KILL`), raw sockets (`NET_RAW`), `mknod` | ||
| (`MKNOD`), `chroot` (`SYS_CHROOT`). Setting the setgid bit on a file whose group | ||
| root is not in (`FSETID`) exits 0 and leaves the bit off. A port below 1024 still | ||
| binds. Before, the container ran with Docker's default capabilities and no process | ||
| limit. `docker-*` results from before this change may not be comparable for a task | ||
| whose step needs a dropped capability: re-run it to compare. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -72,7 +72,8 @@ | |
| ) | ||
| from .claude_json import _last_json_object, _parse_claude_json # noqa: F401 | ||
| from .command import _parse_reward_text | ||
| from .container_agent import AGENT_BIN, DOCKER_STEP_TIMEOUT, FILES_DIR, ContainerSandbox, Docker | ||
| from .container_agent import (AGENT_BIN, DOCKER_STEP_TIMEOUT, FILES_DIR, TASK_CONTAINER_HARDENING, | ||
| ContainerSandbox, Docker) | ||
| from .models import HarnessResult, OperationRecord | ||
| from .network_policy import (DEFAULTS, NetworkPlan, PhasePolicy, build_args, enter_phase, needs_sandbox, | ||
| resolve_recorded, skill_needs, start_args, redact as _redact) | ||
|
|
@@ -352,11 +353,9 @@ def _start_container(self, task: TaskSpec, image: str, container: str, log, | |
| + _task_verify_timeout(task) + 600)) | ||
| self._docker(["rm", "-f", container], log, check=False) | ||
| env_args = [a for k, v in task.container_env.items() for a in ("-e", f"{k}={v}")] | ||
| self._docker( | ||
| ["run", "-d", "--name", container, *net_args, *env_args, | ||
| "--cpus", cpus, "--memory", memory, image, "sleep", str(lifetime)], | ||
| log, | ||
| ) | ||
| run_args = ["run", "-d", "--name", container, *TASK_CONTAINER_HARDENING, *net_args, | ||
| *env_args, "--cpus", cpus, "--memory", memory, image, "sleep", str(lifetime)] | ||
|
Comment on lines
+356
to
+357
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. repos/container.py pairs |
||
| self._docker(run_args, log) | ||
| return enter_phase(plan.solve if inside else DEFAULTS["solve"], container, self._docker, log, | ||
| bridged="bridge" in net_args) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The list of what now fails is not right. Ports below 1024 still work: Docker (20.10+) sets
ip_unprivileged_port_startto 0 inside each container network namespace, so the host value does not matter (checked on Docker 29 with the host at 1024: root andnobodyboth bind port 80 with these flags). On the other side, more steps fail than listed:chroot(SYS_CHROOT),mknod(MKNOD),setcapin a package postinst (SETFCAP), setting setgid bits on files of another group (FSETID). Please drop the NET_BIND_SERVICE case and list the real ones, here, in coding-harnesses.md:296-299 and in the changelog fragment.