landlock

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package landlock confines the console's own file access with Landlock (Linux >= 5.13): once Restrict ran, the process (every thread) may only read beneath the read-only roots, read and execute beneath the exec roots, and write only beneath the read-write ones. It cannot be undone.

It is the second guard of the docker source (spike S2): mounts that the engine propagates under the containers root after the console started (another container's /dev/shm, swarm secrets) are writable tmpfs; beneath a read-only root, Landlock refuses every write, create, remove, rename and, from ABI 3, truncate there. It does not limit reads: beneath a read-only root it grants read on propagated mounts too. Only the docker source's open discipline (RESOLVE_NO_XDEV, the mount-id walk) keeps reads to the approved log files.

Call site (the console, LL-07): after opening the socket and the home directory and reading its configuration, before opening any source:

st, err := landlock.Restrict(landlock.Rules{
	ReadOnly:  append(logRoots, dockerRoot, "/run/locklog-map", <system files read later>),
	ReadWrite: []string{"/run/locklog", "/home/locklog", "/tmp"},
	Exec:      <binaries run later, e.g. the vault CLI>,
})

Every path the console reads after Restrict must be listed (CA bundles, zone info, the resolver's files, /proc/self files, and device files such as /dev/null or /dev/tty): anything else is refused. IOCTL_DEV is never granted, not even beneath the read-write roots, but on a Terminal rule: a character device (the controlling terminal, /dev/tty) read, written and put in no-echo mode by a secret's prompt. Only filesystem access is confined: network and scoping (abstract sockets, signals) are not handled.

Index

Constants

View Source
const (
	// Enforced: every filesystem right of ABI 3 or later is handled (writes,
	// creation, removal, renames and truncation are refused outside the
	// read-write roots).
	Enforced = "enforced"
	// Partial: Landlock runs, but its ABI lacks rights (ABI 1-2: truncate
	// is not handled, so a file writable by permissions can still be
	// truncated).
	Partial = "partial"
	// Unsupported: no Landlock (kernel < 5.13, the LSM disabled, the
	// syscalls blocked by seccomp, or not Linux): no filesystem access is
	// confined.
	Unsupported = "unsupported"
)

State of the confinement.

Variables

This section is empty.

Functions

func ABI

func ABI() (int, string)

ABI returns the Landlock ABI version, or 0 and why there is none.

func UnconfinedNote added in v0.2.0

func UnconfinedNote(st Status) string

UnconfinedNote is the residual of a production profile whose console runs without Landlock (st not Available): its local sources are read by a console no ruleset confines, the read-only mounts its only guard. The console's :status and doctor show it.

Types

type Rules

type Rules struct {
	ReadOnly  []string
	ReadWrite []string
	Exec      []string
	// Terminal are character devices (only) granted read, write and
	// ioctl: the controlling terminal, which a secret's prompt opens and
	// turns the echo off on. A process holding the terminal as its
	// standard streams already has these rights on it.
	Terminal []string
}

Rules are the paths granted: anything else is refused once restricted. A missing path is skipped. Rules on nested paths add up, so a ReadOnly or Exec path at or beneath a ReadWrite one is refused (it would be writable), and so is a ReadWrite path at or beneath an Exec one (write and execute).

type Status

type Status struct {
	State string
	// ABI is the Landlock ABI version (0 when unsupported).
	ABI int
	// Detail says why the state is not Enforced (no secret, no path).
	Detail string
}

Status is the result of Restrict.

func Restrict

func Restrict(r Rules) (Status, error)

Restrict applies r to the whole process (no_new_privs first, as Landlock requires without CAP_SYS_ADMIN). Invalid rules (a relative path, a read-only or exec path at or beneath a read-write one, a read-write path at or beneath an exec one, an unresolvable path) return an error first, on every system and whether or not Landlock is available; nothing is restricted then. Without Landlock it confines nothing and returns Unsupported with a nil error. Any other error means Landlock exists but the ruleset could not be applied (nothing was restricted then, except possibly no_new_privs).

func (Status) Available

func (s Status) Available() bool

Available reports whether a ruleset is enforced, fully or partly.

func (Status) String

func (s Status) String() string

String is the line doctor and :status show, e.g. "landlock enforced (ABI 5)" or "landlock unsupported: kernel without Landlock".

Jump to

Keyboard shortcuts

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