Mark seccomp as partially supported on amd64 and arm64 and document the accepted operation and flags.
Fixes#14627
Co-authored-by: Hanzo Dev <[email protected]>
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
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).
Add an efaproxy driver plug-in for AWS Elastic Fabric Adapter (EFA) devices
bound to the host `efa` driver. EFA's driver-private uverbs ABI carries no
userspace buffer pointers on CQ/QP CREATE: queue memory is kernel-allocated
and handed back via mmap keys in the CREATE response, which the core already
forwards to the host FD verbatim. PrepareCreateDMA is therefore a no-op; the
plug-in exists to register the "efa" driver name and to model EFA's MR_QUERY
driver-namespace method (used by libfabric to fetch RDMA read/write
interconnect IDs).
Model the standard AH object's destroy method (UVERBS_OBJECT_AH): EFA (SRD)
creates address handles via the legacy write path and destroys them through
the modern object, which the core must allow.
Extend the virtual RDMA sysfs for libfabric/hwloc topology discovery:
- device/driver symlink and /sys/bus/pci/drivers/<driver> tree, which
libfabric's EFA provider resolves during device discovery.
- Mirror each PCI node's raw config space ("config" file). hwloc (used by
aws-ofi-nccl to build the NCCL topology) reads it to recover the PCI
bridge bus-number registers; without it hwloc cannot reconstruct the
bridge hierarchy and aws-ofi-nccl aborts its topology write.
- Serve the per-port lid_mask_count attribute alongside the other port
attributes libibverbs reads from sysfs; ib_core creates it on every
port.
The sysfs integration tests cover the new driver tree and config mirroring.
Advertise a >= 5.12 kernel release in RDMA-enabled sandboxes so aws-ofi-nccl
enables dmabuf-based GPU memory registration (ibv_reg_dmabuf_mr), which the
proxy handles via the existing REG_DMABUF_MR path. Sandboxes without RDMA
keep the current 4.19 release to limit the bump's blast radius; a later
change can make the newer release the default.
Co-authored-by: Alessio Ricci Toniolo <[email protected]>
Adds initial scaffolding for eBPF in gVisor. It implements the bpf(2) syscall
with support for BPF_PROG_LOAD, BPF_PROG_QUERY, and BPF_PROG_ATTACH.
Necessary for the cgroups v2 flag to be enabled by default, as this fixes
Docker-in-gVisor with cgroups v2.
This change implements the PointListen trace point to capture details of the
listen syscall, including the file descriptor, backlog, socket family,
socket type, and bound address. It also updates the seccheck metadata for
amd64 and arm64, adds the Listen protobuf message, and includes test coverage.
PiperOrigin-RevId: 952916092
cgroup namespaces are non hierarchical and they are defined primarily by a
"root" cgroup node. The init cgroup namespaces's root node is the true root of
the (only) cgroup2fs tree. The root node of other cgroup namespaces is the
cgroup node of the task at the time of namespace creation.
Residing in a cgroup namespace affects tasks this way:
1) The views into /proc/[pid]/cgroup and the "root" field under
/proc/[pid]/mountinfo are virtualized: they are rendered relative to the
reading task's cgroupns.
2) mount()ing a cgroup2 fs furnishes only a subtree of the full cgroup2fs
tree, rooted at the "root" cgroup of the hosting cgroupns.
Fixes#11989
PiperOrigin-RevId: 948882249
This change introduces a seccheck point for the mmap syscall on both amd64 and
arm64. A new proto message `Mmap` is defined to capture the syscall arguments,
including the file descriptor path when requested. The example seccheck server
is updated to handle the new message type, and a basic test case is added to
the trace tests.
PiperOrigin-RevId: 947914706
Adds stub implementations for:
- sched_setattr(2)
- sched_getattr(2)
- ioprio_set(2)
- ioprio_get(2)
"Support" (with no effect) is included for SCHED_OTHER (referred to in Linux
as SCHED_NORMAL), SCHED_BATCH, and SCHED_IDLE. sched_getscheduler(2) and
sched_setscheduler(2) are updated to support all three as well.
For ioprio_set, the configured I/O priority has no effect.
PiperOrigin-RevId: 938270335
The first step in implementing the new file-descriptor based mount API in
gVisor. A "filesystem creation context" is created using fsopen(). The context
is then configured using fsconfig(), and the FSCONFIG_CMD_CREATE command is
used to create a filesystem. A "mount object" can be obtained using fsmount(),
which can be operated on directly using the *at() functions or mounted onto the
real directory tree using move_mount().
The current implementation has the following limitations:
- Linux passes configuration options to filesystems on-the-fly as fsopen() and
fsconfig() are called, allowing per-parameter error handling. gVisor
currently queues up all options and passes them to the filesystem all-at-once
when FSCONFIG_CMD_CREATE occurs. Lifting this will require refactoring the
option parsing for all existing filesystems.
- Only flag and string arguments to fsconfig() are supported.
- FSCONFIG_CMD_RECONFIGURE is not supported.
- move_mount(): flags MOVE_MOUNT_SET_GROUP and MOVE_MOUNT_BENEATH are not
supported.
- The filesystem context message retrieval interface is not supported.
In the interest of review size, there is no implementation yet for
mount_setattr(2), open_tree(2), or fspick(2).
PiperOrigin-RevId: 931245256
The first step in implementing the new file-descriptor based mount API in
gVisor. A "filesystem creation context" is created using fsopen(). The context
is then configured using fsconfig(), and the FSCONFIG_CMD_CREATE command is
used to create a filesystem. A "mount object" can be obtained using fsmount(),
which can be operated on directly using the *at() functions or mounted onto the
real directory tree using move_mount().
For compatibility reasons, the new mount API is gated behind the runtime flag
`--new-mount-api`, which is disabled by default.
The current implementation has the following limitations:
- Linux passes configuration options to filesystems on-the-fly as fsopen() and
fsconfig() are called, allowing per-parameter error handling. gVisor
currently queues up all options and passes them to the filesystem all-at-once
when FSCONFIG_CMD_CREATE occurs. Lifting this will require refactoring the
option parsing for all existing filesystems.
- Only flag and string arguments to fsconfig() are supported.
- FSCONFIG_CMD_RECONFIGURE is not supported.
- move_mount(): flags MOVE_MOUNT_SET_GROUP and MOVE_MOUNT_BENEATH are not
supported.
- The filesystem context message retrieval interface is not supported.
In the interest of review size, there is no implementation yet for
mount_setattr(2), open_tree(2), or fspick(2).
PiperOrigin-RevId: 923640824
Thus far we were silently ignoring this flag.
While writing the syscall test for this change I realized that we were
using the async-signal-unsafe `FileDescriptor.reset()` (It's unsafe because
it eventually calls `getenv()`) and `exit()`
in various `fork()` contexts, so I fixed the affected syscall tests.
PiperOrigin-RevId: 925064507
This patch introduces pidfd support roughly up to Linux 6.8. Linux selftests
at this version pass, and are now run as an //image_test target. Some features,
like PIDFD_THREAD, that occur later than 6.8 in Linux, are included.
It includes:
- These new syscalls:
- pidfd_open()
- pidfd_getfd()
- pidfd_send_signal()
- New aspects to these existing syscalls:
- waitid() in its support of P_PIDFD
- clone()/clone3() in their support of CLONE_PIDFD
- poll()/epoll()/select() in their support for pidfds
- setns() in its support for pidfds
- pid introspection via /proc/[pid]/fdinfo/[pidfd]
It excludes:
- pidfdfs: pidfds are backed by the anon inode right now
- ioctls to retrieve namespace fds using a pidfd
- process_madvise()
Updates #5839.
PiperOrigin-RevId: 908341658
The linux kernel outputs the current release version to `/proc/sys/kernel/osrelease`. Some libraries read this file to determine which features to enable. Implement the `osrelease`, `ostype`, `version` files to match what is returned for uname.
Fixes: #12487
Some fixes:
* First argument of Task.CopyContext should always be the context.Context
derived from the currently running task, because it is used to get a
CopyScratchBuffer, which must be from the current task. This solved a bunch
of data races.
* Fix logic around which process is remote and which is local. These were
getting mixed up.
* Always read iovec structs (local and remote) from the local process's address
space, since they are syscall arguments. Only use the remote process address
space to read the memory pointed to by the remote iovecs.
* Added ptrace permissions check, per linux.
* Delete unused code from kernel/task_usermem.go
* Rewrote tests so that we read to (write from) a subprocess, rather than the
other way around. So we don't need CAP_PTRACE to run the tests.
* Also make tests async-signal-safe after call to fork(). I think this was the
source of the flakyness on linux previously.
PiperOrigin-RevId: 570506366
The intention of this change is to cover a sufficient surface to accommodate
the use of running Docker within gVisor, rather than a full implementation.
This implements the following features:
- Keys as a first-class concept in the kernel.
- Tracking keys in user namespaces.
- Task session keyrings: possession, inheritance.
- Key permission enforcement.
- The following `keyctl(2)` operations:
- `KEYCTL_GET_KEYRING_ID`
- `KEYCTL_DESCRIBE`
- `KEYCTL_JOIN_SESSION_KEYRING`
- `KEYCTL_SETPERM`
Notably, this does not implement:
- The ability to actually add any keys other than the session keyring
(which does not hold any cryptographic key data).
- Other special keyrings (thread keyring, process keyring, user session
keyring, etc.).
- Lots of `keyctl(2)` operations.
- Key expiration.
- Key garbage collection. Keys live until their user namespace is destroyed.
However, each user namespace is limited to 200 keys, so memory growth is
bounded.
- `add_key(2)`
- `request_key(2)`
... However, this makes design choices that seem odd given the limited scope
of this change, but make sense when taking into account the desire to
eventually accommodate them in the future. For example, there are many
`switch` statements with only one option for session keyrings, which would get
more options when adding support for other special keyrings. Similarly, the
signature of `PossessedKeys` takes in all 3 special "possessed" keyrings, but
currently only ever gets the session keyring as non-nil.
PiperOrigin-RevId: 567047896
This change introduces the nsfs file system. Each new namespace allocates
a new nsfs inode.
Here are reasons why we need these inodes:
* each namespace has to have an unique id.
* proc/pid/ns/ contains one entry for each namespace. Bind mounting one of
the files in this directory to somewhere else in the filesystem keeps the
corresponding namespace alive even if all processes currently in
the namespace terminate.
* setns() allows the calling process to join an existing namespace specified
by a file descriptor.
PiperOrigin-RevId: 550694515
This will be used to plumb the syscall number through to a counter metric that
exports the number of times an unimplemented syscall has been called.
Plenty of syscall implementations call `EmitUnimplementedEvent` for flags and
settings that are not implemented. With `sysno` available, they will be able
to plumb that bit of information through.
PiperOrigin-RevId: 518635831
This flag is added for tests that need to trigger a panic in the sentry
kernel. Only done for x86_64 which does have a dedicated syscall number for
afs_syscall; ARM does not.
PiperOrigin-RevId: 512731631
Syzkaller has found several issues with the two syscalls and a rework is
required. Disable tests and the syscall until issues can be fixed.
PiperOrigin-RevId: 491716795
Added a raw syscall points to all syscalls. Added schematized syscall
points to the following syscalls:
- Chdir
- Fchdir
- Setgid
- Setuid
- Setsid
- Setresuid
- Setresgid
PiperOrigin-RevId: 451001973
Added a raw syscall points to all syscalls. Added schematized syscall
points to the following syscalls:
- read
- close
- socket
- connect
- execve
- creat
- openat
- execveat
Updates #4805
PiperOrigin-RevId: 446008358
Update all instances of the above errors to the faster linuxerr implementation.
With the temporary linuxerr.Equals(), no logical changes are made.
PiperOrigin-RevId: 382306655
Remove three syserror entries duplicated in linuxerr. Because of the
linuxerr.Equals method, this is a mere change of return values from
syserror to linuxerr definitions.
Done with only these three errnos as CLs removing all grow to a significantly
large size.
PiperOrigin-RevId: 382173835