cap

package module
v1.2.69 Latest Latest
Warning

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

Go to latest
Published: May 15, 2023 License: GPL-2.0 Imports: 16 Imported by: 62

README

Package cap is the libcap API for Linux Capabilities written in
Go. The official release announcement site for libcap is:

   https://sites.google.com/site/fullycapable/

Like libcap, the cap package is distributed with a "you choose"
License. Specifically: BSD three clause, or GPL2. See the License
file.

Andrew G. Morgan <morgan@kernel.org>

Documentation

Overview

Package cap provides all the Linux Capabilities userspace library API bindings in native Go.

Capabilities are a feature of the Linux kernel that allow fine grain permissions to perform privileged operations. Privileged operations are required to do irregular system level operations from code. You can read more about how Capabilities are intended to work here:

https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/33528.pdf

This package supports native Go bindings for all the features described in that paper as well as supporting subsequent changes to the kernel for other styles of inheritable Capability.

Some simple things you can do with this package are:

// Read and display the capabilities of the running process
c := cap.GetProc()
log.Printf("this process has these caps:", c)

// Drop any privilege a process might have (including for root,
// but note root 'owns' a lot of system files so a cap-limited
// root can still do considerable damage to a running system).
old := cap.GetProc()
empty := cap.NewSet()
if err := empty.SetProc(); err != nil {
    log.Fatalf("failed to drop privilege: %q -> %q: %v", old, empty, err)
}
now := cap.GetProc()
if cf, _ := now.Cf(empty); cf != 0 {
    log.Fatalf("failed to fully drop privilege: have=%q, wanted=%q", now, empty)
}

The "cap" package operates with POSIX semantics for security state. That is all OS threads are kept in sync at all times. The package "kernel.org/pub/linux/libs/security/libcap/psx" is used to implement POSIX semantics system calls that manipulate thread state uniformly over the whole Go (and any CGo linked) process runtime.

Note, if the Go runtime syscall interface contains the Linux variant syscall.AllThreadsSyscall() API (it debuted in go1.16 see https://github.com/golang/go/issues/1435 for its history) then the "libcap/psx" package will use that to invoke Capability setting system calls in pure Go binaries. With such an enhanced Go runtime, to force this behavior, use the CGO_ENABLED=0 environment variable.

POSIX semantics are more secure than trying to manage privilege at a thread level when those threads share a common memory image as they do under Linux: it is trivial to exploit a vulnerability in one thread of a process to cause execution on any another thread. So, any imbalance in security state, in such cases will readily create an opportunity for a privilege escalation vulnerability.

POSIX semantics also work well with Go, which deliberately tries to insulate the user from worrying about the number of OS threads that are actually running in their program. Indeed, Go can efficiently launch and manage tens of thousands of concurrent goroutines without bogging the program or wider system down. It does this by aggressively migrating idle threads to make progress on unblocked goroutines. So, inconsistent security state across OS threads can also lead to program misbehavior.

The only exception to this process-wide common security state is the cap.Launcher related functionality. This briefly locks an OS thread to a goroutine in order to launch another executable - the robust implementation of this kind of support is quite subtle, so please read its documentation carefully, if you find that you need it.

See https://sites.google.com/site/fullycapable/ for recent updates, some more complete walk-through examples of ways of using 'cap.Set's etc and information on how to file bugs.

Copyright (c) 2019-21 Andrew G. Morgan <morgan@kernel.org>

The cap and psx packages are licensed with a (you choose) BSD 3-clause or GPL2. See LICENSE file for details.

Index

Constants

View Source
const ExtMagic = uint32(0x5101c290)

ExtMagic is the 32-bit (little endian) magic for an external capability set. It can be used to transmit capabilities in binary format in a Linux portable way. The format is: <ExtMagic><byte:length><length-bytes*3-of-cap-data>.

View Source
const LaunchSupported = true

LaunchSupported indicates that is safe to return from a locked OS Thread and have that OS Thread be terminated by the runtime. The Launch functionality really needs to rely on the fact that an excess of runtime.LockOSThread() vs. runtime.UnlockOSThread() calls in a returning go routine will cause the underlying locked OSThread to terminate. That feature was added to the Go runtime in version 1.10.

See these bugs for the discussion and feature assumed by the code in this Launch() functionality:

https://github.com/golang/go/issues/20395
https://github.com/golang/go/issues/20458

A value of false for this constant causes the Launch functionality to fail with an error: cap.ErrNoLaunch. If this value is false you have two choices with respect to the Launch functionality:

  1. don't use cap.(*Launcher).Launch()
  2. upgrade your Go toolchain to 1.10+ (ie., do this one).
View Source
const NamedCount = 41

NamedCount holds the number of capability values, with official names, known at the time this libcap/cap version was released. The "../libcap/cap" package is fully able to manipulate higher numbered capability values by numerical value. However, if you find cap.NamedCount < cap.MaxBits(), it is probably time to upgrade this package on your system.

FWIW the userspace tool '/sbin/capsh' also contains a runtime check for the condition that libcap is behind the running kernel in this way.

Variables

View Source
var ErrAmbiguousAmbient = errors.New("use Launcher for ambient caps")

ErrAmbiguousAmbient indicates that the Launcher is being used in addition to a callback supplied ambient set and the former should be used exclusively in a Launch call.

View Source
var ErrAmbiguousChroot = errors.New("use Launcher for chroot")

ErrAmbiguousChroot indicates that the Launcher is being used in addition to a callback supplied Chroot. The former should be used exclusively for this.

View Source
var ErrAmbiguousIDs = errors.New("use Launcher for uids and gids")

ErrAmbiguousIDs indicates that the Launcher is being used in addition to a callback supplied Credentials. The former should be used exclusively for this.

View Source
var ErrBadMagic = errors.New("unsupported magic")

ErrBadMagic indicates that the kernel preferred magic number for capability Set values is not supported by this package. This generally implies you are using an exceptionally old "../libcap/cap" package. An upgrade is needed, or failing that see https://sites.google.com/site/fullycapable/ for how to file a bug.

View Source
var ErrBadMode = errors.New("unsupported mode")

ErrBadMode is the error returned when an attempt is made to set an unrecognized libcap security mode.

View Source
var ErrBadPath = errors.New("file is not a regular executable")

ErrBadPath indicates a failed attempt to set a file capability on an irregular (non-executable) file.

View Source
var ErrBadSet = errors.New("bad capability set")

ErrBadSet indicates a nil pointer was used for a *Set, or the request of the Set is invalid in some way.

View Source
var ErrBadSize = errors.New("filecap bad size")

ErrBadSize indicates the loaded file capability has an invalid number of bytes in it.

View Source
var ErrBadText = errors.New("bad text")

ErrBadText is returned if the text for a capability set cannot be parsed.

View Source
var ErrBadValue = errors.New("bad capability value")

ErrBadValue indicates a bad capability value was specified.

View Source
var ErrLaunchFailed = errors.New("launch failed")

ErrLaunchFailed is returned if a launch was aborted with no more specific error.

View Source
var ErrNoLaunch = errors.New("launch not supported")

ErrNoLaunch indicates the go runtime available to this binary does not reliably support launching. See cap.LaunchSupported.

View Source
var ErrOutOfRange = errors.New("flag length invalid for export")

ErrOutOfRange indicates an erroneous value for MinExtFlagSize.

View Source
var MinExtFlagSize = uint(8)

MinExtFlagSize defaults to 8 in order to be equivalent to libcap defaults. Setting it to zero can generate smaller external representations. Such smaller representations can be imported by libcap and the Go package just fine, we just default to the default libcap representation for legacy reasons.

Functions

func Differs deprecated

func Differs(cf uint, vec Flag) bool

Differs processes the result of Compare and determines if the Flag's components were different.

Deprecated: Replace with (Diff).Has().

Example, replace this:

diff, err := a.Compare(b)
...
if diff & (1 << Effective) {
   ... different effective capabilities ...
}

with this:

diff, err := a.Cf(b)
...
if diff.Has(Effective) {
   ... different effective capabilities ...
}

func DropBound

func DropBound(val ...Value) error

DropBound attempts to suppress bounding set Values. The kernel will never allow a bounding set Value bit to be raised once successfully dropped. However, dropping requires the current process is sufficiently capable (usually via cap.SETPCAP being raised in the Effective flag of the process' Set). Note, the drops are performed in order and if one bounding value cannot be dropped, the function returns immediately with an error which may leave the system in an ill-defined state. The caller can determine where things went wrong using GetBound().

func GetAmbient

func GetAmbient(val Value) (bool, error)

GetAmbient determines if a specific capability is currently part of the local ambient set. On systems where the ambient set Value is not present, this function returns an error.

func GetBound

func GetBound(val Value) (bool, error)

GetBound determines if a specific capability is currently part of the local bounding set. On systems where the bounding set Value is not present, this function returns an error.

func Prctl added in v1.2.49

func Prctl(prVal uintptr, args ...uintptr) (int, error)

Prctl is a convenience function that performs a syscall.Prctl() that either reads state using a single OS thread, or performs a Prctl that is treated as a process wide setting. It is provided for symmetry reasons, but is equivalent to simply calling the corresponding syscall function.

func Prctlw added in v1.2.49

func Prctlw(prVal uintptr, args ...uintptr) (int, error)

Prctlw is a convenience function for performing a syscall.Prctl() call that executes on all the threads of the process. It is called Prctlw because it is only appropriate to call this function when it is writing thread state that the caller wants to set on all OS threads of the process to observe POSIX semantics when Linux doesn't natively honor them. (Check prctl documentation for when it is appropriate to use this vs. a normal syscall.Prctl() call.)

func ProcRoot added in v1.2.55

func ProcRoot(path string) string

ProcRoot sets the local mount point for the Linux /proc filesystem. It defaults to "/proc", but might be mounted elsewhere on any given system. The function returns the previous value of the local mount point. If the user attempts to set it to "", the value is left unchanged.

func ResetAmbient

func ResetAmbient() error

ResetAmbient attempts to ensure the Ambient set is fully cleared. It works by first reading the set and if it finds any bits raised it will attempt a reset. The test before attempting a reset behavior is a workaround for situations where the Ambient API is locked, but a reset is not actually needed. No Ambient bit not already raised in both the Permitted and Inheritable Set is allowed to be raised by the kernel.

func SetAmbient

func SetAmbient(enable bool, val ...Value) error

SetAmbient attempts to set a specific Value bit to the state, enable. This function will return an error if insufficient permission is available to perform this task. The settings are performed in order and the function returns immediately an error is detected. Use GetAmbient() to unravel where things went wrong. Note, the cap package manages an abstraction IAB that captures all three inheritable vectors in a single type. Consider using that.

func SetGroups

func SetGroups(gid int, suppl ...int) error

SetGroups is a convenience function for robustly setting the GID and all other variants of GID (EGID etc) to the specified value, as well as setting all of the supplementary groups. This function will raise cap.SETGID in order to achieve this operation, and will completely lower the Effective Flag of the process Set before returning.

func SetUID

func SetUID(uid int) error

SetUID is a convenience function for robustly setting the UID and all other variants of UID (EUID etc) to the specified value without dropping the privilege of the current process. This function will raise cap.SETUID in order to achieve this operation, and will completely lower the Effective Flag of the process before returning. Unlike the traditional method of dropping privilege when changing from [E]UID=0 to some other UID, this function only can perform any change of UID if cap.SETUID is available, and this operation will not alter the Permitted Flag of the process' Set.

Types

type Diff added in v1.2.54

type Diff uint

Diff summarizes the result of the (*Set).Cf() function.

func (Diff) Has added in v1.2.54

func (cf Diff) Has(vec Flag) bool

Has processes the Diff result of (*Set).Cf() and determines if the Flag's components were different in that result.

type Flag

type Flag uint

Flag is the type of one of the three Value dimensions held in a Set. It is also used in the (*IAB).Fill() method for changing the Bounding and Ambient Vectors.

const (
	Effective Flag = iota
	Permitted
	Inheritable
)

Effective, Permitted, Inheritable are the three Flags of Values held in a Set.

func (Flag) String added in v0.2.41

func (f Flag) String() string

String identifies a Flag value by its conventional "e", "p" or "i" string abbreviation.

type IAB

type IAB struct {
	// contains filtered or unexported fields
}

IAB holds a summary of all of the inheritable capability vectors: Inh, Amb and Bound. The Bound vector is the logical inverse (two's complement) of the process' Bounding set. That is, raising a Value in the Bound (think blocked) vector is equivalent to dropping that Value from the process' Bounding set. This convention is used to support the empty IAB as being mostly harmless.

func IABFromText

func IABFromText(text string) (*IAB, error)

IABFromText parses a string representing an IAB, as generated by IAB.String(), to generate an IAB.

func IABGetPID added in v1.2.54

func IABGetPID(pid int) (*IAB, error)

IABGetPID returns the IAB tuple of a specified process. The kernel ABI does not support this query via system calls, so the function works by parsing the /proc/<pid>/status file content.

func IABGetProc

func IABGetProc() *IAB

IABGetProc summarizes the Inh, Amb and Bound capability vectors of the current process.

func IABInit deprecated

func IABInit() *IAB

IABInit allocates a new IAB tuple.

Deprecated: Replace with NewIAB.

Example, replace this:

iab := IABInit()

with this:

iab := NewIAB()

func NewIAB added in v1.2.54

func NewIAB() *IAB

NewIAB returns an empty IAB.

func (*IAB) Cf added in v1.2.54

func (iab *IAB) Cf(alt *IAB) (IABDiff, error)

Cf compares two IAB values. Its return value is 0 if the compared tuples are considered identical. The macroscopic differences can be investigated with (IABDiff).Has().

func (*IAB) Dup added in v1.2.60

func (iab *IAB) Dup() (*IAB, error)

Dup returns a duplicate copy of the IAB.

func (*IAB) Fill

func (iab *IAB) Fill(vec Vector, c *Set, flag Flag) error

Fill fills one of the Inh, Amb and Bound capability vectors from one of the flag vectors of a Set. Note, filling the Inh vector will mask the Amb vector, and filling the Amb vector may raise entries in the Inh vector. Further, when filling the Bound vector, the bits are inverted from what you might expect - that is lowered bits from the Set will be raised in the Bound vector.

func (*IAB) GetVector

func (iab *IAB) GetVector(vec Vector, val Value) (bool, error)

GetVector returns the raised state of the specific capability bit of the indicated vector.

func (*IAB) SetProc

func (iab *IAB) SetProc() error

SetProc attempts to change the Inheritable, Ambient and Bounding capability vectors of the current process using the content, iab. The Bounding vector strongly affects the potential for setting other bits, so this function carefully performs the combined operation in the most flexible manner.

func (*IAB) SetVector

func (iab *IAB) SetVector(vec Vector, raised bool, vals ...Value) error

SetVector sets all of the vals in the specified vector to the raised value. Note, the Ambient vector cannot contain values not raised in the Inh vector, so setting values directly in one vector may have the side effect of mirroring the value in the other vector to maintain this constraint. Note, raising a Bound vector bit is equivalent to lowering the Bounding vector of the process (when successfully applied with (*IAB).SetProc()).

func (*IAB) String

func (iab *IAB) String() string

String serializes an IAB to a string format.

type IABDiff added in v1.2.54

type IABDiff uint

IABDiff holds the non-error result of an (*IAB).Cf() function call. It can be interpreted with the function (IABDiff).Has().

func (IABDiff) Has added in v1.2.54

func (d IABDiff) Has(v Vector) bool

Has determines if an IAB comparison differs in a specific vector.

type Launcher

type Launcher struct {
	// contains filtered or unexported fields
}

Launcher holds a configuration for executing an optional callback function and/or launching a child process with capability state different from the parent.

Note, go1.10 is the earliest version of the Go toolchain that can support this abstraction.

func FuncLauncher added in v1.2.49

func FuncLauncher(fn func(interface{}) error) *Launcher

FuncLauncher returns a new launcher whose purpose is to only execute fn in a disposable security context. This is a more bare bones variant of the more elaborate program launcher returned by cap.NewLauncher().

Note, this launcher will fully ignore any overrides provided by the (*Launcher).SetUID() etc. methods. Should your fn() code want to run with a different capability state or other privilege, it should use the cap.*() functions to set them directly. The cap package will ensure that their effects are limited to the runtime of this individual function invocation. Warning: executing non-cap.*() syscall functions may corrupt the state of the program runtime and lead to unpredictable results.

The properties of fn are similar to those supplied via (*Launcher).Callback(fn) method. However, this launcher is bare bones because, when launching, all privilege management performed by the fn() is fully discarded when the fn() completes execution. That is, it does not end by exec()ing some program.

func NewLauncher

func NewLauncher(path string, args []string, env []string) *Launcher

NewLauncher returns a new launcher for the specified program path and args with the specified environment.

func (*Launcher) Callback

func (attr *Launcher) Callback(fn func(*syscall.ProcAttr, interface{}) error)

Callback changes the callback function for Launch() to call before changing privilege. The only thing that is assumed is that the OS thread in use to call this callback function at launch time will be the one that ultimately calls fork to complete the launch of a path specified executable. Any returned error value of said function will terminate the launch process.

A nil fn causes there to be no callback function invoked during a Launch() sequence - it will remove any pre-existing callback.

If the non-nil fn requires any effective capabilities in order to run, they can be raised prior to calling .Launch() or inside the callback function itself.

If the specified callback fn should call any "cap" package functions that change privilege state, these calls will only affect the launch goroutine itself. While the launch is in progress, other (non-launch) goroutines will block if they attempt to change privilege state. These routines will unblock once there are no in-flight launches.

Note, the first argument provided to the callback function is the *syscall.ProcAttr value to be used when a process launch is taking place. A non-nil structure pointer can be modified by the callback to enhance the launch. For example, the .Files field can be overridden to affect how the launched process' stdin/out/err are handled.

Further, the 2nd argument to the callback function is provided at Launch() invocation and can communicate contextual info to and from the callback and the main process.

func (*Launcher) Launch

func (attr *Launcher) Launch(data interface{}) (int, error)

Launch performs a callback function and/or new program launch with a disposable security state. The data object, when not nil, can be used to communicate with the callback. It can also be used to return details from the callback function's execution.

If the attr was created with NewLauncher(), this present function will return the pid of the launched process, or -1 and a non-nil error.

If the attr was created with FuncLauncher(), this present function will return 0, nil if the callback function exits without error. Otherwise it will return -1 and the non-nil error of the callback return value.

Note, while the disposable security state thread makes some operations seem more isolated - they are *not securely isolated*. Launching is inherently violating the POSIX semantics maintained by the rest of the "libcap/cap" package, so think of launching as a convenience wrapper around fork()ing.

Advanced user note: if the caller of this function thinks they know what they are doing by using runtime.LockOSThread() before invoking this function, they should understand that the OS thread invoking (*Launcher).Launch() is *not* guaranteed to be the one used for the disposable security state to perform the launch. If said caller needs to run something on the disposable security state thread, they should do it via the launch callback function mechanism. (The Go runtime is complicated and this is why this Launch mechanism provides the optional callback function.)

func (*Launcher) SetChroot

func (attr *Launcher) SetChroot(root string)

SetChroot specifies the chroot value to be used by the launched command. An empty value means no-change from the prevailing value.

func (*Launcher) SetGroups

func (attr *Launcher) SetGroups(gid int, groups []int)

SetGroups specifies the GID and supplementary groups for the launched command.

func (*Launcher) SetIAB

func (attr *Launcher) SetIAB(iab *IAB)

SetIAB specifies the IAB capability vectors to be inherited by the launched command. A nil value means the prevailing vectors of the parent will be inherited. Note, a duplicate of the provided IAB tuple is actually stored, so concurrent modification of the iab value does not affect the launcher.

func (*Launcher) SetMode

func (attr *Launcher) SetMode(mode Mode)

SetMode specifies the libcap Mode to be used by the launched command.

func (*Launcher) SetUID

func (attr *Launcher) SetUID(uid int)

SetUID specifies the UID to be used by the launched command.

type Mode

type Mode uint

Mode summarizes a complicated secure-bits and capability mode in a libcap preferred way.

const (
	ModeUncertain Mode = iota
	ModeNoPriv
	ModePure1EInit
	ModePure1E
	ModeHybrid
)

ModeUncertain etc are how libcap summarizes security modes involving capabilities and secure-bits.

func GetMode

func GetMode() Mode

GetMode assesses the current process state and summarizes it as a Mode. This function always succeeds. Unfamiliar modes are declared ModeUncertain.

func (Mode) Set

func (m Mode) Set() error

Set attempts to enter the specified mode. An attempt is made to enter the mode, so if you prefer this operation to be a no-op if entering the same mode, call only if CurrentMode() disagrees with the desired mode.

This function will raise cap.SETPCAP in order to achieve this operation, and will completely lower the Effective Flag of the process' Set before returning. This function may fail for lack of permission or because (some of) the Secbits are already locked for the current process.

func (Mode) String

func (m Mode) String() string

String returns the libcap conventional string for this mode.

type Secbits

type Secbits uint

Secbits capture the prctl settable secure-bits of a process.

const (
	SecbitNoRoot Secbits = 1 << iota
	SecbitNoRootLocked
	SecbitNoSetUIDFixup
	SecbitNoSetUIDFixupLocked
	SecbitKeepCaps
	SecbitKeepCapsLocked
	SecbitNoCapAmbientRaise
	SecbitNoCapAmbientRaiseLocked
)

SecbitNoRoot etc are the bitmasks associated with the supported Secbit masks. Source: uapi/linux/securebits.h

func GetSecbits

func GetSecbits() Secbits

GetSecbits returns the current setting of the process' Secbits.

func (Secbits) Set

func (s Secbits) Set() error

Set attempts to force the process Secbits to a value. This function will raise cap.SETPCAP in order to achieve this operation, and will completely lower the Effective Flag of the process upon returning.

type Set

type Set struct {
	// contains filtered or unexported fields
}

Set is an opaque capabilities container for a set of system capbilities. It holds individually addressable capability Value's for the three capability Flag's. See GetFlag() and SetFlag() for how to adjust them individually, and Clear() and ClearFlag() for how to do bulk operations.

For admin tasks associated with managing namespace specific file capabilities, Set can also support a namespace-root-UID value which defaults to zero. See GetNSOwner() and SetNSOwner().

func FromText

func FromText(text string) (*Set, error)

FromText converts the canonical text representation for a Set into a freshly allocated Set.

The format follows the following pattern: a set of space separated sequences. Each sequence applies over the previous sequence to build up a Set. The format of a sequence is:

[comma list of cap_values][[ops][flags]]*

Examples:

"all=ep"
"cap_chown,cap_setuid=ip cap_setuid+e"
"=p cap_setpcap-p+i"

Here "all" refers to all named capabilities known to the hosting kernel, and "all" is assumed if no capabilities are listed before an "=".

The ops values, "=", "+" and "-" imply "reset and raise", "raise" and "lower" respectively. The "e", "i" and "p" characters correspond to the capabilities of the corresponding Flag: "e" (Effective); "i" (Inheritable); "p" (Permitted).

This syntax is overspecified and there are many ways of building the same final Set state. Any sequence that includes a '=' resets the accumulated state of all Flags ignoring earlier sequences. On each of the following lines we give three or more examples of ways to specify a common Set. The last entry on each line is the one generated by (*cap.Set).String() from that Set.

"=p all+ei"  "all=pie"   "=pi all+e"   "=eip"

"cap_setuid=p cap_chown=i"  "cap_chown=ip-p"   "cap_chown=i"

"cap_chown=-p"   "all="   "cap_setuid=pie-pie"   "="

Note: FromText() is tested at release time to completely match the import ability of the libcap:cap_from_text() function.

func GetFd

func GetFd(file *os.File) (*Set, error)

GetFd returns the file capabilities of an open (*os.File).Fd().

func GetFile

func GetFile(path string) (*Set, error)

GetFile returns the file capabilities of a named file.

func GetPID

func GetPID(pid int) (*Set, error)

GetPID returns the capability set associated with the target process id; pid=0 is an alias for current.

func GetProc

func GetProc() *Set

GetProc returns the capability Set of the current process. If the kernel is unable to determine the Set associated with the current process, the function panic()s.

func Import

func Import(d []byte) (*Set, error)

Import imports a Set from a byte array where it has been stored in a portable (lossless) way. That is values exported by libcap.cap_copy_ext() and Export().

func NewSet

func NewSet() *Set

NewSet returns an empty capability set.

func (*Set) Cf added in v1.2.54

func (c *Set) Cf(d *Set) (Diff, error)

Cf returns 0 if c and d are identical. A non-zero Diff value captures a simple macroscopic summary of how they differ. The (Diff).Has() function can be used to determine how the two capability sets differ.

func (*Set) Clear

func (c *Set) Clear() error

Clear fully clears a capability set.

func (*Set) ClearFlag

func (c *Set) ClearFlag(vec Flag) error

ClearFlag clears all the Values associated with the specified Flag.

func (*Set) Compare deprecated

func (c *Set) Compare(d *Set) (uint, error)

Compare returns 0 if c and d are identical in content.

Deprecated: Replace with (*Set).Cf().

Example, replace this:

diff, err := a.Compare(b)
if err != nil {
  return err
}
if diff == 0 {
  return nil
}
if diff & (1 << Effective) {
  log.Print("a and b difference includes Effective values")
}

with this:

diff, err := a.Cf(b)
if err != nil {
  return err
}
if diff == 0 {
  return nil
}
if diff.Has(Effective) {
  log.Print("a and b difference includes Effective values")
}

func (*Set) Dup

func (c *Set) Dup() (*Set, error)

Dup returns a copy of the specified capability set.

func (*Set) Export

func (c *Set) Export() ([]byte, error)

Export exports a Set into a lossless byte array format where it is stored in a portable way. Note, any namespace owner in the Set content is not exported by this function.

Note, Export() generates exported byte streams that are importable by libcap.cap_copy_int() as well as Import().

func (*Set) Fill added in v1.2.51

func (c *Set) Fill(to, from Flag) error

Fill copies the from flag values into the to flag. With this function, you can raise all of the permitted values in the effective flag with c.Fill(cap.Effective, cap.Permitted).

func (*Set) FillFlag added in v1.2.60

func (c *Set) FillFlag(to Flag, ref *Set, from Flag) error

FillFlag copies the from flag values of ref into the to flag of c. With this function, you can raise all of the permitted values in the c Set from those in ref with c.Fill(cap.Permitted, ref, cap.Permitted).

func (*Set) GetFlag

func (c *Set) GetFlag(vec Flag, val Value) (bool, error)

GetFlag determines if the requested Value is enabled in the specified Flag of the capability Set.

func (*Set) GetNSOwner

func (c *Set) GetNSOwner() (int, error)

GetNSOwner returns the namespace owner UID of the capability Set.

func (*Set) SetFd

func (c *Set) SetFd(file *os.File) error

SetFd attempts to set the file capabilities of an open (*os.File).Fd(). This function can also be used to delete a file's capabilities, by calling with c = nil.

Note, Linux does not store the full Effective Flag in the metadata for the file. Only a single Effective bit is stored in this metadata. This single bit is non-zero if the Effective Flag has any overlapping bits with the Permitted or Inheritable Flags of c. This may appear suboptimal, but the reasoning behind it is sound. Namely, the purpose of the Effective bit it to support capabability unaware binaries that will only work if they magically launch with the needed Values already raised (this bit is sometimes referred to simply as the 'legacy' bit).

Historical note: without *full* support for runtime capability manipulation, as it is provided in this "../libcap/cap" package, this was previously the only way for Go programs to make use of file capabilities.

The preferred way that a binary will actually manipulate its file-acquired capabilities is to carefully and deliberately use this package (or libcap, assisted by libpsx, for threaded C/C++ family code).

func (*Set) SetFile

func (c *Set) SetFile(path string) error

SetFile attempts to set the file capabilities of the specified filename. This function can also be used to delete a file's capabilities, by calling with c = nil.

Note, see the comment for SetFd() for some non-obvious behavior of Linux for the Effective Flag on the modified file.

func (*Set) SetFlag

func (c *Set) SetFlag(vec Flag, enable bool, val ...Value) error

SetFlag sets the requested bits to the indicated enable state. This function does not perform any security checks, so values can be set out-of-order. Only when the Set is used to SetProc() etc., will the bits be checked for validity and permission by the kernel. If the function returns an error, the Set will not be modified.

func (*Set) SetNSOwner added in v0.2.41

func (c *Set) SetNSOwner(uid int)

SetNSOwner adds an explicit namespace owner UID to the capability Set. This is only honored when generating file capabilities, and is generally for use by a setup process when installing binaries that use file capabilities to become capable inside a namespace to be administered by that UID. If capability aware code within that namespace writes file capabilities without explicitly setting such a UID, the kernel will fix-up the capabilities to be specific to that owner. In this way, the kernel prevents filesystem capabilities from leaking out of that restricted namespace.

func (*Set) SetProc

func (c *Set) SetProc() error

SetProc attempts to set the capability Set of the current process. The kernel will perform permission checks and an error will be returned if the attempt fails. Should the attempt fail no process capabilities will have been modified.

Note, the general behavior of this call is to set the process-shared capabilities. However, when called from a callback function as part of a (*Launcher).Launch(), the call only sets the capabilities of the thread being used to perform the launch.

func (*Set) String

func (c *Set) String() string

String converts a full capability Set into a single short readable string representation (which may contain spaces). See the cap.FromText() function for an explanation of its return values.

Note (*cap.Set).String() may evolve to generate more compact strings representing the a given Set over time, but it should maintain compatibility with the libcap:cap_to_text() function for any given release. Further, it will always be an inverse of cap.FromText().

type Value

type Value uint

Value is the type of a single capability (or permission) bit.

const (
	// CHOWN allows a process to arbitrarily change the user and
	// group ownership of a file.
	CHOWN Value = iota

	// DAC_OVERRIDE allows a process to override of all Discretionary
	// Access Control (DAC) access, including ACL execute
	// access. That is read, write or execute files that the
	// process would otherwise not have access to. This
	// excludes DAC access covered by cap.LINUX_IMMUTABLE.
	DAC_OVERRIDE

	// DAC_READ_SEARCH allows a process to override all DAC restrictions
	// limiting the read and search of files and
	// directories. This excludes DAC access covered by
	// cap.LINUX_IMMUTABLE.
	DAC_READ_SEARCH

	// FOWNER allows a process to perform operations on files, even
	// where file owner ID should otherwise need be equal to
	// the UID, except where cap.FSETID is applicable. It
	// doesn't override MAC and DAC restrictions.
	//
	// This capability permits the deletion of a file owned
	// by another UID in a directory protected by the sticky
	// (t) bit.
	FOWNER

	// FSETID allows a process to set the S_ISUID and S_ISUID bits of
	// the file permissions, even when the process' effective
	// UID or GID/supplementary GIDs do not match that of the
	// file.
	FSETID

	// KILL allows a process to send a kill(2) signal to any other
	// process - overriding the limitation that there be a
	// [E]UID match between source and target process.
	KILL

	// SETGID allows a process to freely manipulate its own GIDs:
	//   - arbitrarily set the GID, EGID, REGID, RESGID values
	//   - arbitrarily set the supplementary GIDs
	//   - allows the forging of GID credentials passed over a
	//     socket
	SETGID

	// SETUID allows a process to freely manipulate its own UIDs:
	//   - arbitrarily set the UID, EUID, REUID and RESUID
	//     values
	//   - allows the forging of UID credentials passed over a
	//     socket
	SETUID

	// SETPCAP allows a process to freely manipulate its inheritable
	// capabilities.
	//
	// Linux supports the POSIX.1e Inheritable set, the POXIX.1e (X
	// vector) known in Linux as the Bounding vector, as well as
	// the Linux extension Ambient vector.
	//
	// This capability permits dropping bits from the Bounding
	// vector (ie. raising B bits in the libcap IAB
	// representation). It also permits the process to raise
	// Ambient vector bits that are both raised in the Permitted
	// and Inheritable sets of the process. This capability cannot
	// be used to raise Permitted bits, Effective bits beyond those
	// already present in the process' permitted set, or
	// Inheritable bits beyond those present in the Bounding
	// vector.
	//
	// [Historical note: prior to the advent of file capabilities
	// (2008), this capability was suppressed by default, as its
	// unsuppressed behavior was not auditable: it could
	// asynchronously grant its own Permitted capabilities to and
	// remove capabilities from other processes arbitrarily. The
	// former leads to undefined behavior, and the latter is better
	// served by the kill system call.]
	SETPCAP

	// LINUX_IMMUTABLE allows a process to modify the S_IMMUTABLE and
	// S_APPEND file attributes.
	LINUX_IMMUTABLE

	// NET_BIND_SERVICE allows a process to bind to privileged ports:
	//   - TCP/UDP sockets below 1024
	//   - ATM VCIs below 32
	NET_BIND_SERVICE

	// NET_BROADCAST allows a process to broadcast to the network and to
	// listen to multicast.
	NET_BROADCAST

	// NET_ADMIN allows a process to perform network configuration
	// operations:
	//   - interface configuration
	//   - administration of IP firewall, masquerading and
	//     accounting
	//   - setting debug options on sockets
	//   - modification of routing tables
	//   - setting arbitrary process, and process group
	//     ownership on sockets
	//   - binding to any address for transparent proxying
	//     (this is also allowed via cap.NET_RAW)
	//   - setting TOS (Type of service)
	//   - setting promiscuous mode
	//   - clearing driver statistics
	//   - multicasing
	//   - read/write of device-specific registers
	//   - activation of ATM control sockets
	NET_ADMIN

	// NET_RAW allows a process to use raw networking:
	//   - RAW sockets
	//   - PACKET sockets
	//   - binding to any address for transparent proxying
	//     (also permitted via cap.NET_ADMIN)
	NET_RAW

	// IPC_LOCK allows a process to lock shared memory segments for IPC
	// purposes.  Also enables mlock and mlockall system
	// calls.
	IPC_LOCK

	// IPC_OWNER allows a process to override IPC ownership checks.
	IPC_OWNER

	// SYS_MODULE allows a process to initiate the loading and unloading
	// of kernel modules. This capability can effectively
	// modify kernel without limit.
	SYS_MODULE

	// SYS_RAWIO allows a process to perform raw IO:
	//   - permit ioper/iopl access
	//   - permit sending USB messages to any device via
	//     /dev/bus/usb
	SYS_RAWIO

	// SYS_CHROOT allows a process to perform a chroot syscall to change
	// the effective root of the process' file system:
	// redirect to directory "/" to some other location.
	SYS_CHROOT

	// SYS_PTRACE allows a process to perform a ptrace() of any other
	// process.
	SYS_PTRACE

	// SYS_PACCT allows a process to configure process accounting.
	SYS_PACCT

	// SYS_ADMIN allows a process to perform a somewhat arbitrary
	// grab-bag of privileged operations. Over time, this
	// capability should weaken as specific capabilities are
	// created for subsets of cap.SYS_ADMINs functionality:
	//   - configuration of the secure attention key
	//   - administration of the random device
	//   - examination and configuration of disk quotas
	//   - setting the domainname
	//   - setting the hostname
	//   - calling bdflush()
	//   - mount() and umount(), setting up new SMB connection
	//   - some autofs root ioctls
	//   - nfsservctl
	//   - VM86_REQUEST_IRQ
	//   - to read/write pci config on alpha
	//   - irix_prctl on mips (setstacksize)
	//   - flushing all cache on m68k (sys_cacheflush)
	//   - removing semaphores
	//   - Used instead of cap.CHOWN to "chown" IPC message
	//     queues, semaphores and shared memory
	//   - locking/unlocking of shared memory segment
	//   - turning swap on/off
	//   - forged pids on socket credentials passing
	//   - setting readahead and flushing buffers on block
	//     devices
	//   - setting geometry in floppy driver
	//   - turning DMA on/off in xd driver
	//   - administration of md devices (mostly the above, but
	//     some extra ioctls)
	//   - tuning the ide driver
	//   - access to the nvram device
	//   - administration of apm_bios, serial and bttv (TV)
	//     device
	//   - manufacturer commands in isdn CAPI support driver
	//   - reading non-standardized portions of PCI
	//     configuration space
	//   - DDI debug ioctl on sbpcd driver
	//   - setting up serial ports
	//   - sending raw qic-117 commands
	//   - enabling/disabling tagged queuing on SCSI
	//     controllers and sending arbitrary SCSI commands
	//   - setting encryption key on loopback filesystem
	//   - setting zone reclaim policy
	SYS_ADMIN

	// SYS_BOOT allows a process to initiate a reboot of the system.
	SYS_BOOT

	// SYS_NICE allows a process to maipulate the execution priorities
	// of arbitrary processes:
	//   - those involving different UIDs
	//   - setting their CPU affinity
	//   - alter the FIFO vs. round-robin (realtime)
	//     scheduling for itself and other processes.
	SYS_NICE

	// SYS_RESOURCE allows a process to adjust resource related parameters
	// of processes and the system:
	//   - set and override resource limits
	//   - override quota limits
	//   - override the reserved space on ext2 filesystem
	//     (this can also be achieved via cap.FSETID)
	//   - modify the data journaling mode on ext3 filesystem,
	//     which uses journaling resources
	//   - override size restrictions on IPC message queues
	//   - configure more than 64Hz interrupts from the
	//     real-time clock
	//   - override the maximum number of consoles for console
	//     allocation
	//   - override the maximum number of keymaps
	SYS_RESOURCE

	// SYS_TIME allows a process to perform time manipulation of clocks:
	//   - alter the system clock
	//   - enable irix_stime on MIPS
	//   - set the real-time clock
	SYS_TIME

	// SYS_TTY_CONFIG allows a process to manipulate tty devices:
	//   - configure tty devices
	//   - perform vhangup() of a tty
	SYS_TTY_CONFIG

	// MKNOD allows a process to perform privileged operations with
	// the mknod() system call.
	MKNOD

	// LEASE allows a process to take leases on files.
	LEASE

	// AUDIT_WRITE allows a process to write to the audit log via a
	// unicast netlink socket.
	AUDIT_WRITE

	// AUDIT_CONTROL allows a process to configure audit logging via a
	// unicast netlink socket.
	AUDIT_CONTROL

	// SETFCAP allows a process to set capabilities on files.
	// Permits a process to uid_map the uid=0 of the
	// parent user namespace into that of the child
	// namespace. Also, permits a process to override
	// securebits locks through user namespace
	// creation.
	SETFCAP

	// MAC_OVERRIDE allows a process to override Manditory Access Control
	// (MAC) access. Not all kernels are configured with a MAC
	// mechanism, but this is the capability reserved for
	// overriding them.
	MAC_OVERRIDE

	// MAC_ADMIN allows a process to configure the Mandatory Access
	// Control (MAC) policy. Not all kernels are configured
	// with a MAC enabled, but if they are this capability is
	// reserved for code to perform administration tasks.
	MAC_ADMIN

	// SYSLOG allows a process to configure the kernel's syslog
	// (printk) behavior.
	SYSLOG

	// WAKE_ALARM allows a process to trigger something that can wake the
	// system up.
	WAKE_ALARM

	// BLOCK_SUSPEND allows a process to block system suspends - prevent the
	// system from entering a lower power state.
	BLOCK_SUSPEND

	// AUDIT_READ allows a process to read the audit log via a multicast
	// netlink socket.
	AUDIT_READ

	// PERFMON allows a process to enable observability of privileged
	// operations related to performance. The mechanisms
	// include perf_events, i915_perf and other kernel
	// subsystems.
	PERFMON

	// BPF allows a process to manipulate aspects of the kernel
	// enhanced Berkeley Packet Filter (BPF) system. This is
	// an execution subsystem of the kernel, that manages BPF
	// programs. cap.BPF permits a process to:
	//   - create all types of BPF maps
	//   - advanced verifier features:
	//     - indirect variable access
	//     - bounded loops
	//     - BPF to BPF function calls
	//     - scalar precision tracking
	//     - larger complexity limits
	//     - dead code elimination
	//     - potentially other features
	//
	// Other capabilities can be used together with cap.BFP to
	// further manipulate the BPF system:
	//   - cap.PERFMON relaxes the verifier checks as follows:
	//     - BPF programs can use pointer-to-integer
	//       conversions
	//     - speculation attack hardening measures can be
	//       bypassed
	//     - bpf_probe_read to read arbitrary kernel memory is
	//       permitted
	//     - bpf_trace_printk to print the content of kernel
	//       memory
	//   - cap.SYS_ADMIN permits the following:
	//     - use of bpf_probe_write_user
	//     - iteration over the system-wide loaded programs,
	//       maps, links BTFs and convert their IDs to file
	//       descriptors.
	//   - cap.PERFMON is required to load tracing programs.
	//   - cap.NET_ADMIN is required to load networking
	//     programs.
	BPF

	// CHECKPOINT_RESTORE allows a process to perform checkpoint
	// and restore operations. Also permits
	// explicit PID control via clone3() and
	// also writing to ns_last_pid.
	CHECKPOINT_RESTORE
)

CHOWN etc., are the named capability values of the Linux kernel. The canonical source for each name is the "uapi/linux/capabilities.h" file. Some values may not be available (yet) where the kernel is older. The actual number of capabities supported by the running kernel can be obtained using the cap.MaxBits() function.

func FromName

func FromName(name string) (Value, error)

FromName converts a named capability Value to its binary representation.

func MaxBits

func MaxBits() Value

MaxBits returns the number of kernel-named capabilities discovered at runtime in the current system.

func (Value) String

func (v Value) String() string

String converts a capability Value into its canonical text representation.

type Vector

type Vector uint

Vector enumerates which of the inheritable IAB capability vectors is being manipulated.

const (
	Inh Vector = iota
	Amb
	Bound
)

Inh, Amb, Bound enumerate the IAB vector components. (Vector) Inh is equivalent to (Flag) Inheritable. They are named differently for syntax/type checking reasons.

func (Vector) String added in v0.2.41

func (v Vector) String() string

String identifies a Vector value by its conventional I A or B string abbreviation.

Jump to

Keyboard shortcuts

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