3192 Commits
Author SHA1 Message Date
zeekayandHanzo Dev 1fda956476 Set a call's files after its result, and check the magic
Reading a ZAP result writes every field its layout states, the file payload
included, so files attached before decoding were overwritten with none. A
frame whose header is not ZAP is refused at the magic rather than read as a
length.


Co-authored-by: Hanzo Dev <[email protected]>
2026-09-22 23:10:33 -07:00
zeekayandHanzo Dev 04e0b3d153 Delete the packetimpact harness
It was the only thing in the tree importing google.golang.org/grpc, and it
reaches no runsc build path — 71 files of network conformance tests against a
posix_server that is not part of the sandbox. The control plane is urpc, and
now nothing here speaks gRPC at all.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 17:27:54 -07:00
gVisor bot 5128bf5f56 Merge pull request #14519 from dany74q:veth-peer-short-ifinfomsg
PiperOrigin-RevId: 978249831
2026-09-08 19:46:17 -07:00
Etienne PerotandgVisor bot bc480ed7f3 Use //:release BUILD target over //runsc.
PiperOrigin-RevId: 978229308
2026-09-08 18:53:18 -07:00
gVisor bot 801e21b1df Merge pull request #14221 from ayushr2:rename
PiperOrigin-RevId: 976605832
2026-09-04 19:52:38 -07:00
Xin ZhongandgVisor bot 5fc72b21ce seccheck: Add redis benchmarking docs and configs
PiperOrigin-RevId: 976537814
2026-09-04 16:11:23 -07:00
Ayush Ranjan 191f10948f Support RENAME_EXCHANGE in tmpfs and overlayfs
renameat2(2) support was added in 61f761343f ("Implement renameat2."),
but only for the gofer filesystem; tmpfs and overlayfs still return
EINVAL for RENAME_EXCHANGE.

Implement RENAME_EXCHANGE in tmpfs by swapping the two dentries between
their parent directories. When the exchanged files differ in type, the
parents' link counts (for "..") and the exchanged directory's reference
on its parent are transferred.

Implement RENAME_EXCHANGE in overlayfs by copying up the destination
file (and its descendants, if it is a directory) in addition to the
source, and then exchanging both files on the upper layer. Unlike a
regular rename, no whiteout is created at the source location, since
both locations remain occupied. Exchanged directories are marked opaque
at their new locations to prevent merging with lower layer directories
there.

RENAME_EXCHANGE permits the two files to differ in type and does not
require a directory being exchanged to be empty, but exchanging a file
with an ancestor directory must fail with EINVAL; see Linux's
fs/namei.c:__start_renaming(). The gofer filesystem previously required
both files to have the same type; lift that restriction, and update
parent link counts when files of different types are exchanged across
directories.

The RENAME_EXCHANGE syscall tests no longer accept EINVAL; they are
skipped where the flag remains unsupported, i.e. on FUSE and on gVisor
kernels other than runsc. New tests cover mixed-type exchanges and
exchanges with ancestor directories.

Fixes #7895
2026-09-02 17:49:31 +00:00
Shailend ChandandgVisor bot a43cece85a cgroup2fs: fix cpu controller accounting
The cpu controller tracks each task's CPU via a per-instance baseline
snapshot plus a cumulative total for exited tasks, but it never walked
the whole accounting domain when reporting cpu.stat and never reconciled
that state when a controller was disabled or when a task migrated within
a single controller's domain. This caused three accounting errors, each
covered by a new test:

  - Live tasks in descendant cgroups that had not enabled their own cpu
    controller were absent from the ancestor's cpu.stat until they
    exited, even though Linux aggregates descendant usage into the
    ancestor continuously.
  - Migrating a task between two cgroups sharing the same nearest cpu
    controller reset its baseline, discarding the pre-migration CPU.
  - Disabling +cpu discarded the controller's accumulated usage instead
    of reparenting it (Linux folds an offlined css's stats into parent).

Sum the whole domain (the controller's cgroup plus every descendant
without its own cpu controller, recursing into descendants that do) when
reading cpu.stat; leave the baseline untouched on same-instance
migration; and on disable, migrate the domain's tasks to the parent's
nearest cpu controller and fold the accumulated total into it.

PiperOrigin-RevId: 974821312
2026-09-01 18:35:58 -07:00
Shailend ChandandgVisor bot 4a2431a813 cgroup2fs: charge existing tasks on pids controller enablement
Enabling +pids in cgroup.subtree_control creates child pids controllers
with committed = 0, ignoring tasks already present in those cgroups.
pids.current then underreports, and migrating such a task away drives
it negative, since attach() applies deltas unguarded.

Charge a newly instantiated pids controller for the tasks already in
its subtree, both when a parent enables it (rebuildCtrlsLocked) and
when it is returned to the root (returnController). Adds a regression
test.

PiperOrigin-RevId: 974763124
2026-09-01 16:17:01 -07:00
gVisor bot 84e2a9076c Merge pull request #14103 from relkochta:relkochta/openat2
PiperOrigin-RevId: 974743571
2026-09-01 15:37:45 -07:00
Zach KoopmansandgVisor bot d6790de8b9 internal change.
PiperOrigin-RevId: 974706467
2026-09-01 14:28:23 -07:00
Shailend ChandandgVisor bot 30d170b105 cgroup2fs: fix populated accounting when a mid-level cgroup drains
updatePopulated is called when a cgroup's own tasksCount crosses the
0<->1 boundary, but propagated the change to ancestor
nrPopulatedChildren counters even when the cgroup stayed populated
through a child. Draining a mid-level cgroup then made ancestors report
"populated 0" with live tasks below, and the child's later drain
decremented ancestors a second time, leaving the counter permanently
negative.

Skip the notification/propagation walk when the cgroup still has
populated children. Adds a regression test covering both the false
"populated 0" and the stuck-negative counter.

PiperOrigin-RevId: 974662615
2026-09-01 13:09:21 -07:00
Shailend ChandandgVisor bot a6b964a465 Deflake epoll_test
Test incorrectly assumed that epoll_wait returns events in the
exact same order that the file descriptors were registered.

Because epoll_wait returns the events in a randomized order after a
save/restore, we can no longer assume the modified file descriptor
will be at the very end of the result array.

This test started flaking since
https://github.com/google/gvisor/commit/713ef7d7d02a.

PiperOrigin-RevId: 974280975
2026-08-31 22:54:35 -07:00
gVisor bot d31070d68a Merge pull request #14534 from konstantin-s-bogom:setsid-orphan-deadlock-fix
PiperOrigin-RevId: 974150496
2026-08-31 17:02:06 -07:00
Konstantin Bogomolov 30fe0be955 Fix setsid deadlock when orphaning a shared-sighand process group
Scope the signal mutex to just the tg.tty clear in CreateSession, matching how
CreateProcessGroup, JoinProcessGroup, and the exit path already call
handleOrphan without holding a signal mutex.

CreateSession held tg.signalHandlers.mu across the entire process group
manipulation, but it only needs that mutex to clear tg.tty. When setsid(2)
orphans the caller's old process group, decRefWithParent calls handleOrphan,
which locks the signal mutex of every thread group remaining in the group. If
the caller itself, or a sibling thread group that shares the caller's
SignalHandlers (created via clone(CLONE_VM|CLONE_SIGHAND) without CLONE_THREAD),
is still a member, handleOrphan re-locks the already-held, non-reentrant mutex
and the sentry deadlocks while holding TaskSet.mu, freezing the whole sandbox.

Regression test hangs prior to the fix.
2026-08-31 14:29:57 -07:00
Danny Hershko Shemesh c619177102 Refuse a veth peer attribute shorter than its ifinfomsg
The peer payload is sliced at the size of a struct ifinfomsg before anything measures it, so 4 bytes panic the Sentry and take the sandbox with it. Any user reaches it after unshare -Ur -n.

Check the length instead of re-testing a lookup that already succeeded. A short payload now answers EINVAL.

Fixes #14516
2026-08-31 16:08:32 +03:00
Derek MurrayandgVisor bot bf38f77dc7 Implement the copy_file_range(2) syscall.
gVisor returned `ENOSYS` for `copy_file_range(2)`, causing toolchains and
runtimes without fallback paths (such as Zig during linker output generation)
to fail inside sandboxes.

Implement `copy_file_range` as a generic buffered copy in the Sentry to
maintain backing filesystem independence and avoid widening the Sentry seccomp
filter. Argument validation and error handling mirror Linux kernel
`fs/read_write.c` semantics, including offset range checks, cross-device copy
support, and same-file overlap detection.

Add `copy_file_range_test` covering offset handling, short copies, overlap
detection, and Linux errno parity across runsc platforms.

PiperOrigin-RevId: 973465473
2026-08-30 08:41:32 -07:00
gVisor bot 459c3bb7c2 Change default sidecar usage policy to disallow embedded fallback.
PiperOrigin-RevId: 973446500
2026-08-30 07:07:55 -07:00
Etienne PerotandgVisor bot fc9029fcca Change default sidecar usage policy to disallow embedded fallback.
PiperOrigin-RevId: 973308566
2026-08-29 21:40:22 -07:00
Etienne PerotandgVisor bot 4e53fafea2 Use //:release rather than //runsc target for all gVisor test usage
PiperOrigin-RevId: 973178774
2026-08-29 12:57:17 -07:00
Konstantin BogomolovandgVisor bot 58e263886b Implement /proc/sys/fs/mount-max.
It's just a matter of exposing the option via sysfs. Capped to same max as
Linux, to follow convention of what we're already doing with nr_open.

PiperOrigin-RevId: 972901017
2026-08-28 19:02:13 -07:00
gVisor bot a9b7b616c3 Merge pull request #14478 from EtiennePerot:socket-test-fix
PiperOrigin-RevId: 972884938
2026-08-28 18:05:59 -07:00
Etienne Perot 054f876575 Fix //test/syscalls:tcp_socket_test_native failing on newer kernels.
As of Linux commit 5d39580f68e6, SO_ATTACH_FILTER requires
CAP_NET_ADMIN for TCP sockets.

Skip in tests if we don't have it, and update Netstack to require it
too.
2026-08-28 13:16:50 -07:00
Konstantin BogomolovandgVisor bot 9dab4cfd81 Set clone propagation to MS_PRIVATE upon BindAt failure.
This change fixes a mount leak, where a failed bind mount clone would still
remain as part of the mount peergroup. This clone would be found via as the
next entry in mnt.sharedEntry for a new MS_SLAVE mount. The fix is to simply
set the new clone's propagation to MS_PRIVATE, which makes it remove itself
from the peer ring.

This error is demonstrated pretty clearly in the included unit test
(which is mostly LLM-generated, but is relatively straighforward).

Reported-by: [email protected]
PiperOrigin-RevId: 972688916
2026-08-28 11:18:25 -07:00
Ryan El KochtaandgVisor bot 8a645f809f vfs: remove nsfs/cgroup exemptions from umount check for bind mounting
Removes nsfs/cgroupfs's exemptions from umounted checks when bind mounting, and
exempts them from mount namespace checks only for non-recursive binds.

Documents the invariant that umounted children should never have mounted
parents more clearly with a checkInvariants panic in cloneMountTree.

PiperOrigin-RevId: 972149358
2026-08-27 14:11:58 -07:00
Xin ZhongandgVisor bot 03fc2ad2fd Fix CI test flakes in trace_test's Execve trace validation
PiperOrigin-RevId: 970956899
2026-08-25 19:49:29 -07:00
gVisor bot 869ceb6675 Merge pull request #14258 from ayushr2:codex/mm-madvise-file-huge-page
PiperOrigin-RevId: 970658552
2026-08-25 10:59:33 -07:00
Shailend ChandandgVisor bot baf615a53c Replace the experimental --mount-cgroup-v2 flag with in-sandbox-cgroup
The new flag is not a boolean flag, in deference to PR#14197.

PiperOrigin-RevId: 970257422
2026-08-24 20:29:27 -07:00
Shailend ChandandgVisor bot 02534b0728 Test RHEL UBI10, which runs systemd, on gVisor
redhat/ubi10-init covers a second systemd lineage: RHEL 10, systemd
v257, which mandates cgroup v2. The test boots it and checks for failed
units and a working transient unit.

images/systemd/ built systemd from source for a past investigation and
is referenced by nothing.

PiperOrigin-RevId: 970125419
2026-08-24 15:45:30 -07:00
Shailend ChandandgVisor bot d49162dc73 Expand systemd e2e tests
With tests for sandboxing, multiuser, and dockerd:

- Exec sandboxing knobs: PrivateTmp, ProtectSystem=strict, User=, and
  NoNewPrivileges.
- Multiuser operation: two users with their own service managers,
  daemons, journals, and delegated cgroups, isolated from each other.
  User commands run through systemd-machined, which resolves users
  created inside the sandbox (docker exec --user cannot).
- TestSystemdDocker now runs a container instead of stopping at pull.

These tests rely on the two preceding fixes: the NoNewPrivileges probe
reads the new NoNewPrivs line in /proc/[pid]/status, and user-unit
sandboxing fails unless mountinfo shows nodev.

PiperOrigin-RevId: 970106945
2026-08-24 15:12:55 -07:00
Shailend ChandandgVisor bot 67c08dc139 Show nodev in /proc/[pid]/{mounts,mountinfo} and fix noatime rendering.
gVisor stored, locked, and enforced MS_NODEV, but never rendered it. A
remount replaces a mount's whole flag set, so to add a flag userspace
must read the mount's current flags from mountinfo and pass them back.
With nodev missing from that read-back, systemd's sandboxing code
unknowingly requested a remount that would clear nodev — which the
kernel rightly refuses (EPERM) in user namespaces, where preexisting
flags are locked.

Also fix noatime rendering, which overwrote the rw/ro field instead of
appending to it, and match Linux's flag order. Add a syscall test for
both files.

PiperOrigin-RevId: 970083172
2026-08-24 14:32:43 -07:00
Zach KoopmansandgVisor bot 6ec8414e15 Add GKE Sandbox MicroVM runtime support to gke_tester and testcluster.
- Add RuntimeTypeMicroVM with kata-clh handler, microvm RuntimeClass
  overhead, node selector, and toleration configurations.
- Automatically configure nested virtualization when creating MicroVM
  nodepools.
- Add GKE API environment (--env) and endpoint override (--endpoint)
  support for testing against common GKE environments (prod, staging,
  staging2, test). User flags take precedence over environment variables.
- Store endpoint in TestRange and Cluster protos to allow locating
  and deleting clusters across environments.
- Calculate memory requests with headroom to satisfy node allocatable
  limits on GKE nodepools.

PiperOrigin-RevId: 970078173
2026-08-24 14:23:53 -07:00
Shailend ChandandgVisor bot f30d796f52 Show NoNewPrivs in /proc/[pid]/status.
Linux prints the per-thread no_new_privs bit right before the seccomp
line, gVisor tracks the bit but did not surface it.

PiperOrigin-RevId: 969969482
2026-08-24 11:28:28 -07:00
gVisor bot a14bee07ed Merge pull request #14137 from EtiennePerot:le-pinring
PiperOrigin-RevId: 968808565
2026-08-21 18:39:39 -07:00
Parth SarthiandgVisor bot 6ccc20c026 Nftables: Support NFTA_CHAIN_COUNTERS.
Chain Counters count the number
  of packets or bytes the BaseChain evaluated.

PiperOrigin-RevId: 968741662
2026-08-21 16:02:20 -07:00
Shailend ChandandgVisor bot d3cfc9f70e Fix SetAndGetBooleanSocketOptions on Linux 6.16+ hosts
Since Linux 6.16 (7d8d93fdde50), SO_PASSCRED is restricted to AF_UNIX,
AF_NETLINK, and AF_BLUETOOTH sockets; getsockopt on inet sockets fails
with EOPNOTSUPP. This surfaces natively on new kernels and through
hostinet passthrough, while netstack keeps the old semantics. Accept
either behavior.

PiperOrigin-RevId: 968655712
2026-08-21 13:26:59 -07:00
Xin ZhongandgVisor bot b96c95375e Add benchmarking configurations and docs for seccheck.
PiperOrigin-RevId: 968655607
2026-08-21 13:24:05 -07:00
Ayush Ranjan 54e7c8ee0d mm: restore file data after partial huge-page MADV_DONTNEED
Private file mappings can acquire owned huge PMAs after a write breaks
copy-on-write. MemoryManager.Decommit treats those PMAs like private
anonymous memory when MADV_DONTNEED covers only part of a huge page. It
decommits the MemoryFile range in place, replacing discarded file data with
zeroes. Linux instead discards the private copy so later faults reload the
mapped file.

Limit the partial huge-page decommit optimization to anonymous VMAs. Let
file-backed private PMAs follow the normal invalidation path, which drops the
copied pages and restores file contents on the next fault.

Add a syscall test that modifies a huge private file mapping and applies
MADV_DONTNEED to an interior page.
2026-08-21 19:44:24 +00:00
Ryan El Kochta efb3bcd85f Implement openat2(2) in gVisor
Seems that GNU tar extraction has been broken in gVisor since 75b03fd
(11/15/2025), which started using openat2(2) to address CVE-2025-45582.

tar uses openat2(2) for the RESOLVE_BENEATH flag which allows scoping
the path resolution underneath the specified dirfd.

This commit implements openat2(2) in gVisor, with support for all flags
supported by Linux: RESOLVE_BENEATH, RESOLVE_IN_ROOT, RESOLVE_CACHED,
RESOLVE_NO_MAGICLINKS, RESOLVE_NO_SYMLINKS, and RESOLVE_NO_XDEV.

This commit also introduces VirtualFilesystem.renameSeq, a global
sequence counter that along with mountSeq detects mount or rename
operations that race with scoped traversals.

A final "resolved-path-is-under-dirfd" check is performed after
the traversal. This is for two reasons: (1) in case of a bug in
any of the above logic, or (2) in case of an (extremely unlikely)
attack where mountSeq overflows by exactly 2^32 during a path
resolution. Unfortunately, due to the way path traversal in gVisor
is tightly coupled to the operation being performed by a VFS method,
using scoped traversals in an operation that *mutates* anything will
be difficult, since without major refactoring, the check must happen
after the side effect has taken place.

Currently, Linux only exposes scoped traversals through openat2(2),
so destroying the created fd is all we need to do if the final check
fails. (As a result of this limitation, most VFS functions have been
modified to reject scoped traversals "just-in-case".)

The RESOLVE_NO_XDEV implementation has a slight divergence from
Linux. It is a bit looser, permitting absolute symlinks in any case
where the root dentry's mount matches the mount the traversal is
locked to. Linux's behavior here is likely a bug, and since we can
safely be *more* permissive, there's not much reason to match it.

This commit also adds syscall tests and an strace formatter for
openat2(2).
2026-08-21 10:34:56 -07:00
Nayana BidariandgVisor bot 021a58b69d Automated rollback of changelist 964518735
PiperOrigin-RevId: 966690028
2026-08-18 11:04:14 -07:00
Shailend ChandandgVisor bot 5f2770778a Deliver hangup events to blocked pollers on unix socket shutdown
The shutdown notification paths only notified ReadableEvents and
WritableEvents, so a poller waiting only for POLLHUP or POLLRDHUP was
never woken and slept until its timeout. Linux wakes all waiters via
sk_state_change(). Notifications now include EventRdHUp and EventHUp
where the closed direction can newly satisfy them; over-notifying is
harmless since woken waiters re-check readiness.

PiperOrigin-RevId: 966685883
2026-08-18 10:54:48 -07:00
Parth SarthiandgVisor bot 1068b58c2a Nftables: Add iptables-nft integration test target and runner.
- Add iptables-nft test runner and integration test target.
- Makefile to run the tests; will add buildkite later.

PiperOrigin-RevId: 966434729
2026-08-18 01:09:40 -07:00
Parth SarthiandgVisor bot 0724b3e842 Nftables: Support xt_NAT compatibility targets.
Added:
- NAT(SNAT/DNAT) targets to perform network address and port translation.
- XTNATTargetV0, XTNATTargetV1, and XTNATTargetV2 ABI support.
- Fixed NFNATRange2(nf_nat_range2) struct and it's size.
- Unit and syscall tests.

Ref: net/netfilter/xt_nat.c
PiperOrigin-RevId: 966381482
2026-08-17 22:44:58 -07:00
Shailend ChandandgVisor bot 0a789f7147 gofer: dispatch device special file opens to the sentry
A new runsc flag controls the dispatch with the default being to
use sentry implementations alone.

PiperOrigin-RevId: 966266713
2026-08-17 17:17:02 -07:00
gVisor bot 7b85be74c3 Merge pull request #13609 from SamarthBagga:ipv6-addition
PiperOrigin-RevId: 966209546
2026-08-17 15:20:21 -07:00
Shailend ChandandgVisor bot d3bcea91b0 gofer: Take refs when adopting a cached endpoint-bearing inode
When an AF_UNIX socket is bound to a path, the resulting BoundEndpoint is
stored on the gofer inode, and other processes reach it by path: they walk
to the dentry, then pull the endpoint off its inode and connect. Crucially,
a bound socket stays connectable even when no file descriptor is holding
that path open.

The gofer refcounting invariant is: "An additional reference is held on all
synthetic dentries, and on all dentries for which endpoint is non-nil, until
they are unlinked or invalidated."

This purpose of this invariant is for a host-backed bound UDS to stay
resolvable by path even when no FD holds it. A gofer dentry at refs == 0 is
eligible for reclaim; reclaiming it tears down the inode and drops the
HostBoundEndpoint (and its host FD). So the filesystem pins every endpoint-
bearing dentry with one extra ref, held from bind until the name goes away.

This extra ref is dropped unconditionally, guarded only by `endpoint != nil`
in many places: unlinkAt, RenameAt, revalidation/invalidation, filesystem
teardown etc. (These drop paths assume that the invariant holds.)

To establish the invariant the extra ref is taken in the bind paths sure, but
we were missing a reference increment for a dentry that later comes to point
at the same endpoint-bearing inode. This can happen either due to a hard link
or another walk that lands on the same inode.

PiperOrigin-RevId: 966116353
2026-08-17 12:28:06 -07:00
Parth SarthiandgVisor bot 114196c2dc Nftables: Support xt_MASQUERADE compatibility target.
Added:
- `xt_MASQUERADE` target extension.
    Masq can dynamically rewrites the packet's source IP
    to match the outgoing interface's primary IP.
- Masq Revision 0 ABI.
- Unit and syscall tests.

Ref: net/netfilter/xt_masquerade.c
PiperOrigin-RevId: 965062213
2026-08-14 22:38:12 -07:00
gVisor bot 5bcfe695de Merge pull request #14008 from luiscape:luis/map-fixed
PiperOrigin-RevId: 964917211
2026-08-14 15:23:54 -07:00
Nayana BidariandgVisor bot 0890b4de46 Support combined restore of full snapshot and filesystem snapshot.
This change extends the split filesystem checkpoint/restore feature to support
saving and restoring only a subset of filesystems (specified by paths). This
supports a "combined restore" mechanism where some memory files (tmpfs backings)
are restored from the filesystem checkpoint, while others are restored from the
main sentry checkpoint.
- Added `SplitFSCheckpointPaths` to `SaveOpts` to allow specifying paths for
  partial FS checkpoints.
- Updated `createPrivateMemoryFile` to return whether it successfully loaded
  state from the filesystem checkpoint.
- Track which memory files were loaded from the FS checkpoint during restore
  (`fsCheckpointedMfs`) and pass this information to the kernel via context
  (`CtxFSCheckpointedMemoryFiles`).
- In `loadPrivateMemoryFiles` (during sentry restore), only load memory files
  from the sentry checkpoint if they were not already loaded from the FS
  checkpoint.
- Added validation to ensure each memory file is restored from exactly one
  source (no duplicates, and none are missed).

PiperOrigin-RevId: 964518735
2026-08-13 23:52:38 -07:00
Caroline ZhuandgVisor bot d88a427f16 Add rootless Podman in gVisor integration tests.
PiperOrigin-RevId: 964428357
2026-08-13 19:44:27 -07:00