Repository navigation
[release-1.0] Cherry-pick #3580: Restrict actor capabilities.add and make mounts nodev - #3611
Merged
Benjamin Elder (BenTheElder) merged 1 commit intoNov 4, 2026
Conversation
…e#3580) Fixes [agent-substrate#3579](agent-substrate#3579) ### Summary Restricts `securityContext.capabilities.add` to a hardened allowlist of 12 Linux capabilities and blocks dangerous capabilities such as `MKNOD`, `SYS_ADMIN`, and `SYS_RAWIO` before 1.0. In microVM sandboxes, granting `MKNOD` to a container running as root allows it to create block device nodes matching the guest's `virtio-pmem` root disk and directly write to the guest filesystem. Other capabilities like `SYS_ADMIN` and `SYS_RAWIO` expose dangerous guest kernel attack surface. ### Changes * **Capability Allowlist:** `securityContext.capabilities.add` now only permits 12 capabilities required for package installs, non-root user switches, and standard container workflows: * `AUDIT_WRITE` * `CHOWN` * `DAC_OVERRIDE` * `FOWNER` * `FSETID` * `KILL` * `NET_BIND_SERVICE` * `SETFCAP` * `SETGID` * `SETPCAP` * `SETUID` * `SYS_CHROOT` * **Admission Enforcement:** `ateapi` and `atelet` reject actor template creations and updates specifying capabilities outside this allowlist. * **Drop Unrestricted:** `securityContext.capabilities.drop` continues to accept any capability name. * **MicroVM Hardening:** * Volume bind mounts are now mounted with `nodev`, and the microVM guest mounts the virtio-fs share with `nodev` (covering automounted submounts and rootfs). `ShapeGVisor` strips `nodev`, keeping gVisor specs identical and preserving checkpoint/restore compatibility. * MicroVM guest sysctl `net.ipv4.ping_group_range = "0 2147483647"` is configured so standard unprivileged `ping` continues to work without requiring `NET_RAW`. * **Documentation & Schemas:** Updated `api-guide.md`, `sandbox-classes.md`, and regenerated protobuf bindings (`ateapi.pb.go`, `atelet.pb.go`). ### Breaking change: gVisor `MEMORY` snapshots taken before this release won't restore gVisor now gets `nodev` on volume and system mounts (`/proc`, `/dev/shm`, `/sys`, `/tmp`), matching microVM. runsc applies it to the host bind mount. `runsc restore` rejects a checkpoint whose mounts differ from the new spec (`"Mounts" does not match across checkpoint restore`), so gVisor `MEMORY` snapshots taken before the upgrade can't be restored. rc.2 already breaks these snapshots with [agent-substrate#3533](agent-substrate#3533) (tmpfs `/dev/shm` and `/tmp`), so this adds no new upgrade step on top of that. MicroVM actors are unaffected. **What breaks:** - Suspended gVisor actors whose latest snapshot is `MEMORY` fidelity (the default) move to `ACTOR_STATE_CRASHED` on `ResumeActor`. - New actors from gVisor templates created before the upgrade crash on first resume, because the template's golden snapshot is an old `MEMORY` checkpoint. **Upgrade steps:** 1. **Before upgrading,** resume any suspended gVisor actor whose in-memory state you need, and save that state to durable storage or let its work finish. 2. **Re-create gVisor templates.** `ActorTemplate` is immutable, so create a new template (e.g. `my-template-v2`), or delete and re-create it, to build a new golden snapshot. Point clients at the new template. 3. **Replace crashed actors.** `RevertActor` won't help: it reverts to the same pre-upgrade checkpoint, which crashes again. `UpdateActor --template` won't either, because resume restores the actor's own snapshot. Delete the actor and create it again from the new template. Its in-memory state and its snapshot's rootfs and volume contents are lost. ### Testing * **Unit Tests:** Updated resource validation tests, parity tests, and microVM spec tests (`go test ./...` passes in container). * **Live GKE Testing (`sgke-rc1`):** * Verified template rejection when adding `MKNOD` or `SYS_ADMIN`. * Verified unprivileged ICMP `ping` works in microVM guests without `NET_RAW`. * Verified that pre-existing gVisor actor snapshots restore cleanly. * **e2e Probe Coverage:** * Verified inside the guest that `mknod` fails with `EPERM`. * Verified that unprivileged users can open `SOCK_DGRAM`/`IPPROTO_ICMP` sockets across both runtimes. Thanks to [Fabiano Fidêncio (@fidencio)](https://github.com/fidencio) for the report on MKNOD that led us to make this change. --------- Signed-off-by: Greg Castle <[email protected]> (cherry picked from commit 17fa858) Signed-off-by: dberkov <[email protected]>
Dmitry Berkovich (dberkov)
force-pushed
the
release-1.0-cherry-pick-3580
branch
from
November 4, 2026 01:17
7c89953 to
08ebd00
Compare
Benjamin Elder (BenTheElder)
approved these changes
Nov 4, 2026
Benjamin Elder (BenTheElder)
merged commit Nov 4, 2026
e59281c
into
agent-substrate:release-1.0
9 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cherry-pick of #3580 onto
release-1.0(git cherry-pick -xof the squash commit), it applied cleanly with no changes. Fixes #3579 for the release branch.securityContext.capabilities.addis restricted to a 12-capability allowlist at admission in bothateapiandatelet;dropstill accepts any name. Volume bind mounts and gVisor system mounts gainnodev, and the microVM guest setsnet.ipv4.ping_group_rangeso unprivilegedpingkeeps working withoutNET_RAW.AI use: AI-assisted. Clean pick.
This carries the same breaking changes as #3580: templates adding
MKNOD,SYS_ADMIN,SYS_RAWIOor anything else outside the allowlist are now rejected, and gVisorMEMORYsnapshots taken before the upgrade no longer restore. The snapshot break is already present in rc.2 via #3533, so it adds no new upgrade step; see #3580 for the upgrade notes.🤖 Generated with Claude Code