github.com/sagernet/gvisor@v0.0.0-20240428053021-e691de28565f/pkg/abi/linux/capability.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package linux
    16  
    17  import (
    18  	"strings"
    19  )
    20  
    21  // A Capability represents the ability to perform a privileged operation.
    22  type Capability int
    23  
    24  // Capabilities defined by Linux. Taken from the kernel's
    25  // include/uapi/linux/capability.h. See capabilities(7) or that file for more
    26  // detailed capability descriptions.
    27  const (
    28  	CAP_CHOWN              = Capability(0)
    29  	CAP_DAC_OVERRIDE       = Capability(1)
    30  	CAP_DAC_READ_SEARCH    = Capability(2)
    31  	CAP_FOWNER             = Capability(3)
    32  	CAP_FSETID             = Capability(4)
    33  	CAP_KILL               = Capability(5)
    34  	CAP_SETGID             = Capability(6)
    35  	CAP_SETUID             = Capability(7)
    36  	CAP_SETPCAP            = Capability(8)
    37  	CAP_LINUX_IMMUTABLE    = Capability(9)
    38  	CAP_NET_BIND_SERVICE   = Capability(10)
    39  	CAP_NET_BROADCAST      = Capability(11)
    40  	CAP_NET_ADMIN          = Capability(12)
    41  	CAP_NET_RAW            = Capability(13)
    42  	CAP_IPC_LOCK           = Capability(14)
    43  	CAP_IPC_OWNER          = Capability(15)
    44  	CAP_SYS_MODULE         = Capability(16)
    45  	CAP_SYS_RAWIO          = Capability(17)
    46  	CAP_SYS_CHROOT         = Capability(18)
    47  	CAP_SYS_PTRACE         = Capability(19)
    48  	CAP_SYS_PACCT          = Capability(20)
    49  	CAP_SYS_ADMIN          = Capability(21)
    50  	CAP_SYS_BOOT           = Capability(22)
    51  	CAP_SYS_NICE           = Capability(23)
    52  	CAP_SYS_RESOURCE       = Capability(24)
    53  	CAP_SYS_TIME           = Capability(25)
    54  	CAP_SYS_TTY_CONFIG     = Capability(26)
    55  	CAP_MKNOD              = Capability(27)
    56  	CAP_LEASE              = Capability(28)
    57  	CAP_AUDIT_WRITE        = Capability(29)
    58  	CAP_AUDIT_CONTROL      = Capability(30)
    59  	CAP_SETFCAP            = Capability(31)
    60  	CAP_MAC_OVERRIDE       = Capability(32)
    61  	CAP_MAC_ADMIN          = Capability(33)
    62  	CAP_SYSLOG             = Capability(34)
    63  	CAP_WAKE_ALARM         = Capability(35)
    64  	CAP_BLOCK_SUSPEND      = Capability(36)
    65  	CAP_AUDIT_READ         = Capability(37)
    66  	CAP_PERFMON            = Capability(38)
    67  	CAP_BPF                = Capability(39)
    68  	CAP_CHECKPOINT_RESTORE = Capability(40)
    69  
    70  	// CAP_LAST_CAP is the highest-numbered capability.
    71  	// Search for "CAP_LAST_CAP" to find other places that need to change.
    72  	CAP_LAST_CAP = CAP_CHECKPOINT_RESTORE
    73  )
    74  
    75  // Ok returns true if cp is a supported capability.
    76  func (cp Capability) Ok() bool {
    77  	return cp >= 0 && cp <= CAP_LAST_CAP
    78  }
    79  
    80  // String returns the capability name.
    81  func (cp Capability) String() string {
    82  	switch cp {
    83  	case CAP_CHOWN:
    84  		return "CAP_CHOWN"
    85  	case CAP_DAC_OVERRIDE:
    86  		return "CAP_DAC_OVERRIDE"
    87  	case CAP_DAC_READ_SEARCH:
    88  		return "CAP_DAC_READ_SEARCH"
    89  	case CAP_FOWNER:
    90  		return "CAP_FOWNER"
    91  	case CAP_FSETID:
    92  		return "CAP_FSETID"
    93  	case CAP_KILL:
    94  		return "CAP_KILL"
    95  	case CAP_SETGID:
    96  		return "CAP_SETGID"
    97  	case CAP_SETUID:
    98  		return "CAP_SETUID"
    99  	case CAP_SETPCAP:
   100  		return "CAP_SETPCAP"
   101  	case CAP_LINUX_IMMUTABLE:
   102  		return "CAP_LINUX_IMMUTABLE"
   103  	case CAP_NET_BIND_SERVICE:
   104  		return "CAP_NET_BIND_SERVICE"
   105  	case CAP_NET_BROADCAST:
   106  		return "CAP_NET_BROADCAST"
   107  	case CAP_NET_ADMIN:
   108  		return "CAP_NET_ADMIN"
   109  	case CAP_NET_RAW:
   110  		return "CAP_NET_RAW"
   111  	case CAP_IPC_LOCK:
   112  		return "CAP_IPC_LOCK"
   113  	case CAP_IPC_OWNER:
   114  		return "CAP_IPC_OWNER"
   115  	case CAP_SYS_MODULE:
   116  		return "CAP_SYS_MODULE"
   117  	case CAP_SYS_RAWIO:
   118  		return "CAP_SYS_RAWIO"
   119  	case CAP_SYS_CHROOT:
   120  		return "CAP_SYS_CHROOT"
   121  	case CAP_SYS_PTRACE:
   122  		return "CAP_SYS_PTRACE"
   123  	case CAP_SYS_PACCT:
   124  		return "CAP_SYS_PACCT"
   125  	case CAP_SYS_ADMIN:
   126  		return "CAP_SYS_ADMIN"
   127  	case CAP_SYS_BOOT:
   128  		return "CAP_SYS_BOOT"
   129  	case CAP_SYS_NICE:
   130  		return "CAP_SYS_NICE"
   131  	case CAP_SYS_RESOURCE:
   132  		return "CAP_SYS_RESOURCE"
   133  	case CAP_SYS_TIME:
   134  		return "CAP_SYS_TIME"
   135  	case CAP_SYS_TTY_CONFIG:
   136  		return "CAP_SYS_TTY_CONFIG"
   137  	case CAP_MKNOD:
   138  		return "CAP_MKNOD"
   139  	case CAP_LEASE:
   140  		return "CAP_LEASE"
   141  	case CAP_AUDIT_WRITE:
   142  		return "CAP_AUDIT_WRITE"
   143  	case CAP_AUDIT_CONTROL:
   144  		return "CAP_AUDIT_CONTROL"
   145  	case CAP_SETFCAP:
   146  		return "CAP_SETFCAP"
   147  	case CAP_MAC_OVERRIDE:
   148  		return "CAP_MAC_OVERRIDE"
   149  	case CAP_MAC_ADMIN:
   150  		return "CAP_MAC_ADMIN"
   151  	case CAP_SYSLOG:
   152  		return "CAP_SYSLOG"
   153  	case CAP_WAKE_ALARM:
   154  		return "CAP_WAKE_ALARM"
   155  	case CAP_BLOCK_SUSPEND:
   156  		return "CAP_BLOCK_SUSPEND"
   157  	case CAP_AUDIT_READ:
   158  		return "CAP_AUDIT_READ"
   159  	default:
   160  		return "UNKNOWN"
   161  	}
   162  }
   163  
   164  // TrimmedString returns the capability name without the "CAP_" prefix.
   165  func (cp Capability) TrimmedString() string {
   166  	const capPrefix = "CAP_"
   167  	s := cp.String()
   168  	if !strings.HasPrefix(s, capPrefix) {
   169  		return s
   170  	}
   171  	// This could use strings.TrimPrefix, but that function doesn't guarantee
   172  	// that it won't allocate a new string, whereas string slicing does.
   173  	// In the case of this function, since Capability.String returns a constant
   174  	// string, the underlying set of bytes backing that string will never be
   175  	// garbage-collected. Therefore, we always want to use a string slice that
   176  	// points to this same constant set of bytes, rather than risking
   177  	// allocating a new string.
   178  	return s[len(capPrefix):]
   179  }
   180  
   181  // CapabilityFromString converts a string to a capability.
   182  // If the capability doesn't exist, its second return value is `false`.
   183  // The capability name is expected to include the "CAP_" prefix.
   184  func CapabilityFromString(capability string) (Capability, bool) {
   185  	for cp := Capability(0); cp <= CAP_LAST_CAP; cp++ {
   186  		if !cp.Ok() {
   187  			continue
   188  		}
   189  		if cp.String() == capability {
   190  			return cp, true
   191  		}
   192  	}
   193  	return -1, false
   194  }
   195  
   196  // AllCapabilities returns a list of all defined capabilities.
   197  func AllCapabilities() []Capability {
   198  	allCapapabilities := make([]Capability, 0, CAP_LAST_CAP+1)
   199  	for cp := Capability(0); cp <= CAP_LAST_CAP; cp++ {
   200  		if !cp.Ok() {
   201  			continue
   202  		}
   203  		allCapapabilities = append(allCapapabilities, cp)
   204  	}
   205  	return allCapapabilities
   206  }
   207  
   208  // Version numbers used by the capget/capset syscalls, defined in Linux's
   209  // include/uapi/linux/capability.h.
   210  const (
   211  	// LINUX_CAPABILITY_VERSION_1 causes the data pointer to be
   212  	// interpreted as a pointer to a single cap_user_data_t. Since capability
   213  	// sets are 64 bits and the "capability sets" in cap_user_data_t are 32
   214  	// bits only, this causes the upper 32 bits to be implicitly 0.
   215  	LINUX_CAPABILITY_VERSION_1 = 0x19980330
   216  
   217  	// LINUX_CAPABILITY_VERSION_2 and LINUX_CAPABILITY_VERSION_3 cause the
   218  	// data pointer to be interpreted as a pointer to an array of 2
   219  	// cap_user_data_t, using the second to store the 32 MSB of each capability
   220  	// set. Versions 2 and 3 are identical, but Linux printk's a warning on use
   221  	// of version 2 due to a userspace API defect.
   222  	LINUX_CAPABILITY_VERSION_2 = 0x20071026
   223  	LINUX_CAPABILITY_VERSION_3 = 0x20080522
   224  
   225  	// HighestCapabilityVersion is the highest supported
   226  	// LINUX_CAPABILITY_VERSION_* version.
   227  	HighestCapabilityVersion = LINUX_CAPABILITY_VERSION_3
   228  )
   229  
   230  // Constants that are used by file capability extended attributes, defined
   231  // in Linux's include/uapi/linux/capability.h.
   232  const (
   233  	// The flag decides the value of effective file capabilit
   234  	VFS_CAP_FLAGS_EFFECTIVE = 0x000001
   235  	// VFS_CAP_REVISION_1 was the original file capability implementation,
   236  	// which supported 32-bit masks for file capabilities.
   237  	VFS_CAP_REVISION_1 = 0x01000000
   238  	// VFS_CAP_REVISION_2 allows for file capability masks that are 64
   239  	// bits in size, and was necessary as the number of supported
   240  	// capabilities grew beyond 32.
   241  	VFS_CAP_REVISION_2 = 0x02000000
   242  	// VFS_CAP_REVISION_3 are provided to support namespaced file capabilities.
   243  	// As with version 2 file capabilities, version 3 capability
   244  	// masks are 64 bits in size.  But in addition, the root user
   245  	// ID of namespace is encoded in the security.capability
   246  	// extended attribute.
   247  	VFS_CAP_REVISION_3    = 0x03000000
   248  	VFS_CAP_REVISION_MASK = 0xFF000000
   249  	// The encoded VFS_CAP_REVISION_1 data's number of bytes.
   250  	XATTR_CAPS_SZ_1 = 12
   251  	// The encoded VFS_CAP_REVISION_2 data's number of bytes.
   252  	XATTR_CAPS_SZ_2 = 20
   253  	// The encoded VFS_CAP_REVISION_3 data's number of bytes.
   254  	XATTR_CAPS_SZ_3 = 24
   255  )
   256  
   257  // CapUserHeader is equivalent to Linux's cap_user_header_t.
   258  //
   259  // +marshal
   260  type CapUserHeader struct {
   261  	Version uint32
   262  	Pid     int32
   263  }
   264  
   265  // CapUserData is equivalent to Linux's cap_user_data_t.
   266  //
   267  // +marshal slice:CapUserDataSlice
   268  type CapUserData struct {
   269  	Effective   uint32
   270  	Permitted   uint32
   271  	Inheritable uint32
   272  }