caps

package
v0.0.5 Latest Latest
Warning

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

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package caps keeps a cloop process's Linux capabilities where they belong: with the process itself, and with the one program it starts that needs one.

The executor agent is installed holding CAP_NET_ADMIN (Task 20352), because installing a sandbox's firewall means loading an nftables ruleset and nft(8) cannot do that without it. systemd can only hand a capability to a service that runs as an ordinary user through the *ambient* set, and the ambient set is inherited: left alone, every program the agent starts would hold the capability too — the harness, its shell, git and the hooks git runs from a workload's own repository. A host-mode workload could then rewrite the host's packet filter, including the rules that confine its neighbours' sandboxes.

So the capability stops at the agent. Confine clears the ambient and inheritable sets on every thread before the process starts anything, which leaves the agent holding CAP_NET_ADMIN (permitted and effective) and every child holding nothing. Grant then hands it back to exactly one kind of child: the nft(8) invocations in pkg/netfilter.

Clearing has to reach every thread, because Linux keeps capabilities per thread and Go forks from whichever thread a goroutine happens to be on. A build without cgo does it with syscall.AllThreadsSyscall. A build with cgo cannot — the runtime refuses, since it cannot see threads C code started — so there a C constructor clears both sets before the Go runtime has started its first thread, and every thread inherits the result. Both paths are exercised by caps_linux_test.go against a process started with a real ambient set.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Confine

func Confine() error

Confine stops this process's capabilities from flowing to the programs it starts. It clears the ambient and inheritable sets on every thread and leaves the permitted and effective sets alone, so the process keeps whatever it holds and can still Grant a capability to a particular child.

It is a no-op for a process that holds nothing to pass on, which is every ordinary invocation of cloop, and it is safe to call more than once. It returns an error only when the process does hold something inheritable and could not clear it — which means its children would inherit it.

func Grant

func Grant(cmd *exec.Cmd, c Cap) bool

Grant arranges for cmd, once started, to hold c — when this process holds c and is not root. A root child needs no grant: it gets every capability in its bounding set at exec anyway. Grant reports whether it asked for one.

It must be called before cmd starts. A child whose exec cannot honour the grant fails to start rather than running without the capability, so a caller sees the failure at the point it matters.

func Has

func Has(set uint64, c Cap) bool

Has reports whether c is in set.

func Holds

func Holds(c Cap) bool

Holds reports whether this process holds c in its permitted set and may therefore hand it to a child. Root is not special-cased: a root process that has dropped c does not hold it.

Types

type Cap

type Cap uint

Cap is a Linux capability number, as capabilities(7) numbers them.

const NetAdmin Cap = 12

NetAdmin is CAP_NET_ADMIN: what nft(8) needs to read or load a ruleset.

func (Cap) String

func (c Cap) String() string

String names the capability the way systemd and capabilities(7) do.

type Sets

type Sets struct {
	Inheritable, Permitted, Effective, Bounding, Ambient uint64
}

Sets is one thread's capability sets, as /proc reports them.

func ParseStatus

func ParseStatus(status string) (Sets, error)

ParseStatus reads the Cap* lines of a /proc/<pid>/status file.

Jump to

Keyboard shortcuts

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