Files

273 lines
8.5 KiB
Go
Raw Permalink Normal View History

// Copyright 2018 The gVisor Authors.
2018-04-27 10:37:02 -07:00
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package linux
import (
"strings"
)
2018-04-27 10:37:02 -07:00
// A Capability represents the ability to perform a privileged operation.
type Capability int
// Capabilities defined by Linux. Taken from the kernel's
// include/uapi/linux/capability.h. See capabilities(7) or that file for more
// detailed capability descriptions.
const (
CAP_CHOWN = Capability(0)
CAP_DAC_OVERRIDE = Capability(1)
CAP_DAC_READ_SEARCH = Capability(2)
CAP_FOWNER = Capability(3)
CAP_FSETID = Capability(4)
CAP_KILL = Capability(5)
CAP_SETGID = Capability(6)
CAP_SETUID = Capability(7)
CAP_SETPCAP = Capability(8)
CAP_LINUX_IMMUTABLE = Capability(9)
CAP_NET_BIND_SERVICE = Capability(10)
CAP_NET_BROADCAST = Capability(11)
CAP_NET_ADMIN = Capability(12)
CAP_NET_RAW = Capability(13)
CAP_IPC_LOCK = Capability(14)
CAP_IPC_OWNER = Capability(15)
CAP_SYS_MODULE = Capability(16)
CAP_SYS_RAWIO = Capability(17)
CAP_SYS_CHROOT = Capability(18)
CAP_SYS_PTRACE = Capability(19)
CAP_SYS_PACCT = Capability(20)
CAP_SYS_ADMIN = Capability(21)
CAP_SYS_BOOT = Capability(22)
CAP_SYS_NICE = Capability(23)
CAP_SYS_RESOURCE = Capability(24)
CAP_SYS_TIME = Capability(25)
CAP_SYS_TTY_CONFIG = Capability(26)
CAP_MKNOD = Capability(27)
CAP_LEASE = Capability(28)
CAP_AUDIT_WRITE = Capability(29)
CAP_AUDIT_CONTROL = Capability(30)
CAP_SETFCAP = Capability(31)
CAP_MAC_OVERRIDE = Capability(32)
CAP_MAC_ADMIN = Capability(33)
CAP_SYSLOG = Capability(34)
CAP_WAKE_ALARM = Capability(35)
CAP_BLOCK_SUSPEND = Capability(36)
CAP_AUDIT_READ = Capability(37)
CAP_PERFMON = Capability(38)
CAP_BPF = Capability(39)
CAP_CHECKPOINT_RESTORE = Capability(40)
2018-04-27 10:37:02 -07:00
2019-06-21 10:55:38 -07:00
// CAP_LAST_CAP is the highest-numbered capability.
2023-10-25 12:06:44 -07:00
// Search for "CAP_LAST_CAP" to find other places that need to change.
CAP_LAST_CAP = CAP_CHECKPOINT_RESTORE
2018-04-27 10:37:02 -07:00
)
// Ok returns true if cp is a supported capability.
func (cp Capability) Ok() bool {
2019-06-21 10:55:38 -07:00
return cp >= 0 && cp <= CAP_LAST_CAP
2018-04-27 10:37:02 -07:00
}
2019-06-10 23:37:32 -07:00
// String returns the capability name.
func (cp Capability) String() string {
switch cp {
case CAP_CHOWN:
return "CAP_CHOWN"
case CAP_DAC_OVERRIDE:
return "CAP_DAC_OVERRIDE"
case CAP_DAC_READ_SEARCH:
return "CAP_DAC_READ_SEARCH"
case CAP_FOWNER:
return "CAP_FOWNER"
case CAP_FSETID:
return "CAP_FSETID"
case CAP_KILL:
return "CAP_KILL"
case CAP_SETGID:
return "CAP_SETGID"
case CAP_SETUID:
return "CAP_SETUID"
case CAP_SETPCAP:
return "CAP_SETPCAP"
case CAP_LINUX_IMMUTABLE:
return "CAP_LINUX_IMMUTABLE"
case CAP_NET_BIND_SERVICE:
return "CAP_NET_BIND_SERVICE"
case CAP_NET_BROADCAST:
return "CAP_NET_BROADCAST"
case CAP_NET_ADMIN:
return "CAP_NET_ADMIN"
case CAP_NET_RAW:
return "CAP_NET_RAW"
case CAP_IPC_LOCK:
return "CAP_IPC_LOCK"
case CAP_IPC_OWNER:
return "CAP_IPC_OWNER"
case CAP_SYS_MODULE:
return "CAP_SYS_MODULE"
case CAP_SYS_RAWIO:
return "CAP_SYS_RAWIO"
case CAP_SYS_CHROOT:
return "CAP_SYS_CHROOT"
case CAP_SYS_PTRACE:
return "CAP_SYS_PTRACE"
case CAP_SYS_PACCT:
return "CAP_SYS_PACCT"
case CAP_SYS_ADMIN:
return "CAP_SYS_ADMIN"
case CAP_SYS_BOOT:
return "CAP_SYS_BOOT"
case CAP_SYS_NICE:
return "CAP_SYS_NICE"
case CAP_SYS_RESOURCE:
return "CAP_SYS_RESOURCE"
case CAP_SYS_TIME:
return "CAP_SYS_TIME"
case CAP_SYS_TTY_CONFIG:
return "CAP_SYS_TTY_CONFIG"
case CAP_MKNOD:
return "CAP_MKNOD"
case CAP_LEASE:
return "CAP_LEASE"
case CAP_AUDIT_WRITE:
return "CAP_AUDIT_WRITE"
case CAP_AUDIT_CONTROL:
return "CAP_AUDIT_CONTROL"
case CAP_SETFCAP:
return "CAP_SETFCAP"
case CAP_MAC_OVERRIDE:
return "CAP_MAC_OVERRIDE"
case CAP_MAC_ADMIN:
return "CAP_MAC_ADMIN"
case CAP_SYSLOG:
return "CAP_SYSLOG"
case CAP_WAKE_ALARM:
return "CAP_WAKE_ALARM"
case CAP_BLOCK_SUSPEND:
return "CAP_BLOCK_SUSPEND"
case CAP_AUDIT_READ:
return "CAP_AUDIT_READ"
default:
return "UNKNOWN"
}
}
// TrimmedString returns the capability name without the "CAP_" prefix.
func (cp Capability) TrimmedString() string {
const capPrefix = "CAP_"
s := cp.String()
if !strings.HasPrefix(s, capPrefix) {
return s
}
// This could use strings.TrimPrefix, but that function doesn't guarantee
// that it won't allocate a new string, whereas string slicing does.
// In the case of this function, since Capability.String returns a constant
// string, the underlying set of bytes backing that string will never be
// garbage-collected. Therefore, we always want to use a string slice that
// points to this same constant set of bytes, rather than risking
// allocating a new string.
return s[len(capPrefix):]
}
// CapabilityFromString converts a string to a capability.
// If the capability doesn't exist, its second return value is `false`.
// The capability name is expected to include the "CAP_" prefix.
func CapabilityFromString(capability string) (Capability, bool) {
for cp := Capability(0); cp <= CAP_LAST_CAP; cp++ {
if !cp.Ok() {
continue
}
if cp.String() == capability {
return cp, true
}
}
return -1, false
}
// AllCapabilities returns a list of all defined capabilities.
func AllCapabilities() []Capability {
allCapapabilities := make([]Capability, 0, CAP_LAST_CAP+1)
for cp := Capability(0); cp <= CAP_LAST_CAP; cp++ {
if !cp.Ok() {
continue
}
allCapapabilities = append(allCapapabilities, cp)
}
return allCapapabilities
}
2018-04-27 10:37:02 -07:00
// Version numbers used by the capget/capset syscalls, defined in Linux's
// include/uapi/linux/capability.h.
const (
// LINUX_CAPABILITY_VERSION_1 causes the data pointer to be
// interpreted as a pointer to a single cap_user_data_t. Since capability
// sets are 64 bits and the "capability sets" in cap_user_data_t are 32
// bits only, this causes the upper 32 bits to be implicitly 0.
LINUX_CAPABILITY_VERSION_1 = 0x19980330
// LINUX_CAPABILITY_VERSION_2 and LINUX_CAPABILITY_VERSION_3 cause the
// data pointer to be interpreted as a pointer to an array of 2
// cap_user_data_t, using the second to store the 32 MSB of each capability
// set. Versions 2 and 3 are identical, but Linux printk's a warning on use
// of version 2 due to a userspace API defect.
LINUX_CAPABILITY_VERSION_2 = 0x20071026
LINUX_CAPABILITY_VERSION_3 = 0x20080522
// HighestCapabilityVersion is the highest supported
// LINUX_CAPABILITY_VERSION_* version.
HighestCapabilityVersion = LINUX_CAPABILITY_VERSION_3
)
// Constants that are used by file capability extended attributes, defined
// in Linux's include/uapi/linux/capability.h.
const (
// The flag decides the value of effective file capabilit
VFS_CAP_FLAGS_EFFECTIVE = 0x000001
// VFS_CAP_REVISION_1 was the original file capability implementation,
// which supported 32-bit masks for file capabilities.
VFS_CAP_REVISION_1 = 0x01000000
// VFS_CAP_REVISION_2 allows for file capability masks that are 64
// bits in size, and was necessary as the number of supported
// capabilities grew beyond 32.
VFS_CAP_REVISION_2 = 0x02000000
// VFS_CAP_REVISION_3 are provided to support namespaced file capabilities.
// As with version 2 file capabilities, version 3 capability
// masks are 64 bits in size. But in addition, the root user
// ID of namespace is encoded in the security.capability
// extended attribute.
VFS_CAP_REVISION_3 = 0x03000000
VFS_CAP_REVISION_MASK = 0xFF000000
// The encoded VFS_CAP_REVISION_1 data's number of bytes.
XATTR_CAPS_SZ_1 = 12
// The encoded VFS_CAP_REVISION_2 data's number of bytes.
XATTR_CAPS_SZ_2 = 20
// The encoded VFS_CAP_REVISION_3 data's number of bytes.
XATTR_CAPS_SZ_3 = 24
)
2018-04-27 10:37:02 -07:00
// CapUserHeader is equivalent to Linux's cap_user_header_t.
//
// +marshal
2018-04-27 10:37:02 -07:00
type CapUserHeader struct {
Version uint32
Pid int32
}
// CapUserData is equivalent to Linux's cap_user_data_t.
//
// +marshal slice:CapUserDataSlice
2018-04-27 10:37:02 -07:00
type CapUserData struct {
Effective uint32
Permitted uint32
Inheritable uint32
}