sandboxsetup

package
v0.0.0-...-648dfe1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2026 License: Apache-2.0, BSD-3-Clause, MIT Imports: 21 Imported by: 0

Documentation

Overview

Package sandboxsetup provides helpers for setting up gVisor sandboxes.

Package sandboxsetup provides helpers for setting up gVisor sandboxes.

Package sandboxsetup provides helpers for setting up gVisor sandboxes.

Package sandboxsetup provides helpers for setting up gVisor sandboxes.

Index

Constants

View Source
const ProcFDBindMount = "/proc/fs"

ProcFDBindMount is the path where /proc/self/fd is bind-mounted inside the gofer's mount tree. Redhat distros don't allow bind-mounts in /proc/self directories due to SELinux rules.

Variables

AllCapTypes is the set of all Linux capability types.

View Source
var CapFromName = map[string]capability.Cap{
	"CAP_CHOWN":              capability.CAP_CHOWN,
	"CAP_DAC_OVERRIDE":       capability.CAP_DAC_OVERRIDE,
	"CAP_DAC_READ_SEARCH":    capability.CAP_DAC_READ_SEARCH,
	"CAP_FOWNER":             capability.CAP_FOWNER,
	"CAP_FSETID":             capability.CAP_FSETID,
	"CAP_KILL":               capability.CAP_KILL,
	"CAP_SETGID":             capability.CAP_SETGID,
	"CAP_SETUID":             capability.CAP_SETUID,
	"CAP_SETPCAP":            capability.CAP_SETPCAP,
	"CAP_LINUX_IMMUTABLE":    capability.CAP_LINUX_IMMUTABLE,
	"CAP_NET_BIND_SERVICE":   capability.CAP_NET_BIND_SERVICE,
	"CAP_NET_BROADCAST":      capability.CAP_NET_BROADCAST,
	"CAP_NET_ADMIN":          capability.CAP_NET_ADMIN,
	"CAP_NET_RAW":            capability.CAP_NET_RAW,
	"CAP_IPC_LOCK":           capability.CAP_IPC_LOCK,
	"CAP_IPC_OWNER":          capability.CAP_IPC_OWNER,
	"CAP_SYS_MODULE":         capability.CAP_SYS_MODULE,
	"CAP_SYS_RAWIO":          capability.CAP_SYS_RAWIO,
	"CAP_SYS_CHROOT":         capability.CAP_SYS_CHROOT,
	"CAP_SYS_PTRACE":         capability.CAP_SYS_PTRACE,
	"CAP_SYS_PACCT":          capability.CAP_SYS_PACCT,
	"CAP_SYS_ADMIN":          capability.CAP_SYS_ADMIN,
	"CAP_SYS_BOOT":           capability.CAP_SYS_BOOT,
	"CAP_SYS_NICE":           capability.CAP_SYS_NICE,
	"CAP_SYS_RESOURCE":       capability.CAP_SYS_RESOURCE,
	"CAP_SYS_TIME":           capability.CAP_SYS_TIME,
	"CAP_SYS_TTY_CONFIG":     capability.CAP_SYS_TTY_CONFIG,
	"CAP_MKNOD":              capability.CAP_MKNOD,
	"CAP_LEASE":              capability.CAP_LEASE,
	"CAP_AUDIT_WRITE":        capability.CAP_AUDIT_WRITE,
	"CAP_AUDIT_CONTROL":      capability.CAP_AUDIT_CONTROL,
	"CAP_SETFCAP":            capability.CAP_SETFCAP,
	"CAP_MAC_OVERRIDE":       capability.CAP_MAC_OVERRIDE,
	"CAP_MAC_ADMIN":          capability.CAP_MAC_ADMIN,
	"CAP_SYSLOG":             capability.CAP_SYSLOG,
	"CAP_WAKE_ALARM":         capability.CAP_WAKE_ALARM,
	"CAP_BLOCK_SUSPEND":      capability.CAP_BLOCK_SUSPEND,
	"CAP_AUDIT_READ":         capability.CAP_AUDIT_READ,
	"CAP_PERFMON":            capability.CAP_PERFMON,
	"CAP_BPF":                capability.CAP_BPF,
	"CAP_CHECKPOINT_RESTORE": capability.CAP_CHECKPOINT_RESTORE,
}

CapFromName maps Linux capability string names to their capability.Cap values.

Functions

func AdjustMountOptions

func AdjustMountOptions(conf *config.Config, path string, opts []string) ([]string, error)

AdjustMountOptions adds filesystem-specific gofer mount options.

func ApplyCaps

func ApplyCaps(caps *specs.LinuxCapabilities) error

ApplyCaps applies the capabilities in the spec to the current thread.

Precondition: Must be called with the current OS thread locked (runtime.LockOSThread).

func CallSelfAsNobody

func CallSelfAsNobody(args []string) error

CallSelfAsNobody sets UID and GID to nobody and then execve's itself again.

func CapsFromNames

func CapsFromNames(names []string) ([]capability.Cap, error)

CapsFromNames converts capability string names to capability.Cap values.

func CopyFile

func CopyFile(dst, src string) error

CopyFile copies a file from src to dst.

func ExecProcUmounter

func ExecProcUmounter() (*exec.Cmd, *os.File)

ExecProcUmounter executes a child process that umounts /proc when the returned pipe is closed.

func GetCaps

func GetCaps(which capability.CapType, caps *specs.LinuxCapabilities) []string

GetCaps returns the capability names for the given capability type from the provided LinuxCapabilities spec.

func NewSocket

func NewSocket(ioFD int) *unet.Socket

NewSocket creates a unet.Socket from a file descriptor. It fatally exits if the socket cannot be created.

func PivotRoot

func PivotRoot(root string) error

PivotRoot changes the root filesystem to the given directory using pivot_root(2). The old root is unmounted after the pivot.

func PrepareArgs

func PrepareArgs(subCmdName string, fSet *flag.FlagSet, override map[string]string) []string

PrepareArgs returns the args that can be used to re-execute the current program. It manipulates the flags of the subcommand identified by subCmdName and fSet is the flag.FlagSet of this subcommand. It applies the flags specified by override map. In case of conflict, flag is overridden.

Postcondition: PrepareArgs() takes ownership of override map.

func ResolveMounts

func ResolveMounts(conf *config.Config, mounts []specs.Mount, root string, mountConfs []specutils.GoferMountConf) ([]specs.Mount, error)

ResolveMounts resolves relative paths and symlinks in mount point destinations. It also adjusts mount options based on the underlying filesystem type.

Note: mount points must already be in place for resolution to work. Otherwise, it may follow symlinks to locations that would be overwritten with another mount point and return the wrong location. In short, make sure SetupMounts() has been called before.

func ResolveSymlinks(root, rel string) (string, error)

ResolveSymlinks walks 'rel' having 'root' as the root directory. If there are symlinks, they are evaluated relative to 'root' to ensure the end result is the same as if the process was running inside the container.

func SetCapsAndCallSelf

func SetCapsAndCallSelf(args []string, caps *specs.LinuxCapabilities) error

SetCapsAndCallSelf sets capabilities to the current thread and then execve's itself again with the arguments specified in 'args' to restart the process with the desired capabilities.

func SetupDev

func SetupDev(spec *specs.Spec, conf *config.Config, root, procPath string) error

SetupDev mounts devices from the OCI spec into the gofer's /dev directory.

func SetupMounts

func SetupMounts(conf *config.Config, mounts []specs.Mount, root, procPath string, mountConfs []specutils.GoferMountConf, mountOpener MountOpener) (retErr error)

SetupMounts bind-mounts all mounts specified in the spec in their correct location inside root. It resolves relative paths and symlinks, and creates directories as needed.

mountConfs is indexed such that mountConfs[0] is the root filesystem configuration, and mount iteration starts at index 1. mountOpener is called when the gofer process cannot directly access a mount source. It may be nil if all mounts are directly accessible.

func SetupRootFS

func SetupRootFS(spec *specs.Spec, conf *config.Config, mountConfs []specutils.GoferMountConf, devIoFD int, mountOpener MountOpener, containerID string, bundleDir string) error

SetupRootFS prepares the filesystem the gofer will serve to the sandbox. There are some gVisor-specific quirks:

  • The gofer runs with minimal capabilities (see runsc/cmd/gofer.go). However, gofer startup requires more capabilities (for example, pivot_root(2) requires CAP_SYS_ADMIN).
  • As a result, the gofer sets up the container rootfs, does pivot_root(2), and then re-executes itself while dropping extra capabilities.
  • To re-execute itself, it requires access to `/proc/self/exe` after pivot_root(2).

For this reason, we can't just pivot_root(2) into the container rootfs path (i.e. spec.Root.Path), as it would mean bind-mounting host /proc inside spec.Root.Path, which might be a read-only filesystem.

Furthermore, createContainer hooks from the OCI spec need to run before the pivot_root(2) and expect the container rootfs to be prepared at spec.Root.Path with all the bind-mounts in place.

To satisfy all of these requirements, this is the approach we take:

  1. We prepare all the bind-mounts in `spec.Root.Path` and execute the createContainer hooks.
  2. We create a new tmpfs mount at /proc/fs.
  3. We bind-mount host /proc and spec.Root.Path onto /proc/fs/proc and /proc/fs/root, respectively.
  4. We then pivot_root(2) into /proc/fs. Now host procfs is accessible via /proc/ and container rootfs is accessible via /root.
  5. We re-exec the gofer binary and drop extra capabilities.
  6. We unmount the /proc bind mount.
  7. We chroot(2) into /root (note that the gofer runs with CAP_SYS_CHROOT).

This function does steps 1-4.

mountConfs must be indexed such that mountConfs[0] is the root filesystem configuration and subsequent entries correspond to spec mounts with mount configs.

func ShouldExposeNvidiaDevice

func ShouldExposeNvidiaDevice(path string) bool

ShouldExposeNvidiaDevice returns true if path refers to an Nvidia device which should be exposed to the container.

Precondition: nvproxy is enabled.

func ShouldExposeTpuDevice

func ShouldExposeTpuDevice(path string) bool

ShouldExposeTpuDevice returns true if path refers to a TPU device which should be exposed to the container.

Precondition: tpuproxy is enabled.

func ShouldExposeVFIODevice

func ShouldExposeVFIODevice(path string) bool

ShouldExposeVFIODevice returns true if path refers to a VFIO device which should be exposed to the container.

func TrimCaps

func TrimCaps(names []string, setter capability.Capabilities) ([]capability.Cap, error)

TrimCaps filters the named capabilities to only those that are currently permitted by the given Capabilities set.

func UmountProc

func UmountProc(syncFD int)

UmountProc writes to syncFD signalling the process started by ExecProcUmounter() to umount /proc.

func WaitForFD

func WaitForFD(fd int, fdName string) error

WaitForFD waits for the other end of a given FD to be closed. The FD is closed unconditionally after that. This should only be called for actual FDs (i.e. fd >= 0).

func WriteMounts

func WriteMounts(mountsFD int, mounts []specs.Mount) error

WriteMounts serializes the given mounts as JSON and writes them to the given file descriptor.

Types

type IntFlags

type IntFlags []int

IntFlags can be used with int flags that appear multiple times. It supports comma-separated lists too.

func (*IntFlags) Get

func (i *IntFlags) Get() any

Get implements flag.Value.

func (*IntFlags) GetArray

func (i *IntFlags) GetArray() []int

GetArray returns an array of ints.

func (*IntFlags) GetFDs

func (i *IntFlags) GetFDs() []*fd.FD

GetFDs returns an array of *fd.FD.

func (*IntFlags) Set

func (i *IntFlags) Set(s string) error

Set implements flag.Value. Set(String()) should be idempotent.

func (*IntFlags) String

func (i *IntFlags) String() string

String implements flag.Value.

type MountOpener

type MountOpener func(m *specs.Mount, flags uint32) (*os.File, error)

MountOpener is used in two cases:

(1) when the gofer process cannot access a mount source directly (e.g. due to permission restrictions in a user namespace). In this case, the returned file is just the opened mount source.

(2) when the mount is id-mapped, which the gofer process cannot configure on its own. In this case, the returned file is an open_tree() detached mount point which has had the requested id mapping configured using mount_setattr().

The caller is responsible for closing the returned file.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL