github.com/hpcng/singularity@v3.1.1+incompatible/pkg/util/capabilities/capabilities.go (about)

     1  // Copyright (c) 2018, Sylabs Inc. All rights reserved.
     2  // This software is licensed under a 3-clause BSD license. Please consult the
     3  // LICENSE.md file distributed with the sources of this project regarding your
     4  // rights to use or distribute this software.
     5  
     6  package capabilities
     7  
     8  import "strings"
     9  
    10  const (
    11  	// Permitted capability string constant.
    12  	Permitted string = "permitted"
    13  	// Effective capability string constant.
    14  	Effective = "effective"
    15  	// Inheritable capability string constant.
    16  	Inheritable = "inheritable"
    17  	// Ambient capability string constant.
    18  	Ambient = "ambient"
    19  	// Bounding capability string constant.
    20  	Bounding = "bounding"
    21  )
    22  
    23  type capability struct {
    24  	Name        string
    25  	Value       uint
    26  	Description string
    27  }
    28  
    29  var (
    30  	capChown = &capability{
    31  		Name:  "CAP_CHOWN",
    32  		Value: 0,
    33  		Description: `CAP_CHOWN
    34  	Make arbitrary changes to file UIDs and GIDs (see chown(2)).`,
    35  	}
    36  
    37  	capDacOverride = &capability{
    38  		Name:  "CAP_DAC_OVERRIDE",
    39  		Value: 1,
    40  		Description: `CAP_DAC_OVERRIDE
    41  	Bypass file read, write, and execute permission checks. (DAC is an abbreviation of "discretionary access control".)`,
    42  	}
    43  
    44  	capDacReadSearch = &capability{
    45  		Name:  "CAP_DAC_READ_SEARCH",
    46  		Value: 2,
    47  		Description: `CAP_DAC_READ_SEARCH
    48  	* Bypass file read permission checks and directory read and execute permission checks.
    49  	* Invoke open_by_handle_at(2).`,
    50  	}
    51  
    52  	capFowner = &capability{
    53  		Name:  "CAP_FOWNER",
    54  		Value: 3,
    55  		Description: `CAP_FOWNER
    56  	* Bypass permission checks on operations that normally require the filesystem UID of the process to match the UID of
    57  	  the file (e.g., chmod(2), utime(2)), excluding those operations covered by CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH.
    58  	* set extended file attributes (see chattr(1)) on arbitrary files.
    59  	* set Access Control Lists (ACLs) on arbitrary files.
    60  	* ignore directory sticky bit on file deletion.
    61  	* specify O_NOATIME for arbitrary files in open(2) and fcntl(2).`,
    62  	}
    63  
    64  	capFsetid = &capability{
    65  		Name:  "CAP_FSETID",
    66  		Value: 4,
    67  		Description: `CAP_FSETID
    68  	Don't  clear set-user-ID and set-group-ID mode bits when a file is modified; set the set-group-ID bit for a file whose
    69  	GID does not match the filesystem or any of the supplementary GIDs of the calling process.`,
    70  	}
    71  
    72  	capKill = &capability{
    73  		Name:  "CAP_KILL",
    74  		Value: 5,
    75  		Description: `CAP_KILL
    76  	Bypass permission checks for sending signals (see kill(2)). This includes use of the ioctl(2) KDSIGACCEPT operation.`,
    77  	}
    78  
    79  	capSetgid = &capability{
    80  		Name:  "CAP_SETGID",
    81  		Value: 6,
    82  		Description: `CAP_SETGID
    83  	Make arbitrary manipulations of process GIDs and supplementary GID list; forge GID when passing socket credentials via
    84  	UNIX domain sockets; write a group ID mapping in a user namespace (see user_namespaces(7)).`,
    85  	}
    86  
    87  	capSetuid = &capability{
    88  		Name:  "CAP_SETUID",
    89  		Value: 7,
    90  		Description: `CAP_SETUID
    91  	Make arbitrary manipulations of process UIDs (setuid(2), setreuid(2), setresuid(2), setfsuid(2)); forge UID when pass‐
    92  	ing socket credentials via UNIX domain sockets; write a user ID mapping in a user namespace (see user_namespaces(7)).`,
    93  	}
    94  
    95  	capSetpcap = &capability{
    96  		Name:  "CAP_SETPCAP",
    97  		Value: 8,
    98  		Description: `CAP_SETPCAP
    99  	If file capabilities are not supported: grant or remove any capability in the caller's permitted capability set to or
   100  	from any other process. (This property of CAP_SETPCAP is not available when the kernel is configured to support file
   101  	capabilities, since CAP_SETPCAP has entirely different semantics for such kernels.)
   102  
   103  	If file capabilities are supported: add any capability from the calling thread's bounding set to its inheritable set;
   104  	drop capabilities from the bounding set (via prctl(2) PR_CAPBSET_DROP); make changes to the securebits flags.`,
   105  	}
   106  
   107  	capLinuxImmutable = &capability{
   108  		Name:  "CAP_LINUX_IMMUTABLE",
   109  		Value: 9,
   110  		Description: `CAP_LINUX_IMMUTABLE
   111  	Set the FS_APPEND_FL and FS_IMMUTABLE_FL inode flags (see chattr(1)).`,
   112  	}
   113  
   114  	capNetBindService = &capability{
   115  		Name:  "CAP_NET_BIND_SERVICE",
   116  		Value: 10,
   117  		Description: `CAP_NET_BIND_SERVICE
   118  	Bind a socket to Internet domain privileged ports (port numbers less than 1024).`,
   119  	}
   120  
   121  	capNetBroadcast = &capability{
   122  		Name:  "CAP_NET_BROADCAST",
   123  		Value: 11,
   124  		Description: `CAP_NET_BROADCAST
   125  	(Unused)  Make socket broadcasts, and listen to multicasts.`,
   126  	}
   127  
   128  	capNetAdmin = &capability{
   129  		Name:  "CAP_NET_ADMIN",
   130  		Value: 12,
   131  		Description: `CAP_NET_ADMIN
   132  	Perform various network-related operations:
   133  	* interface configuration.
   134  	* administration of IP firewall, masquerading, and accounting.
   135  	* modify routing tables.
   136  	* bind to any address for transparent proxying.
   137  	* set type-of-service (TOS)
   138  	* clear driver statistics.
   139  	* set promiscuous mode.
   140  	* enabling multicasting.
   141  	* use setsockopt(2) to set the following socket options: SO_DEBUG, SO_MARK, SO_PRIORITY (for a priority outside the
   142  	  range 0 to 6), SO_RCVBUFFORCE, and SO_SNDBUFFORCE.`,
   143  	}
   144  
   145  	capNetRaw = &capability{
   146  		Name:  "CAP_NET_RAW",
   147  		Value: 13,
   148  		Description: `CAP_NET_RAW
   149  	* use RAW and PACKET sockets.
   150  	* bind to any address for transparent proxying.`,
   151  	}
   152  
   153  	capIpcLock = &capability{
   154  		Name:  "CAP_IPC_LOCK",
   155  		Value: 14,
   156  		Description: `CAP_IPC_LOCK
   157  	Lock memory (mlock(2), mlockall(2), mmap(2), shmctl(2)).`,
   158  	}
   159  
   160  	capIpcOwner = &capability{
   161  		Name:  "CAP_IPC_OWNER",
   162  		Value: 15,
   163  		Description: `CAP_IPC_OWNER
   164  	Bypass permission checks for operations on System V IPC objects.`,
   165  	}
   166  
   167  	capSysModule = &capability{
   168  		Name:  "CAP_SYS_MODULE",
   169  		Value: 16,
   170  		Description: `CAP_SYS_MODULE
   171  	Load and unload kernel modules (see init_module(2) and delete_module(2)); in kernels before 2.6.25: drop capabilities
   172  	from the system-wide capability bounding set.`,
   173  	}
   174  
   175  	capSysRawio = &capability{
   176  		Name:  "CAP_SYS_RAWIO",
   177  		Value: 17,
   178  		Description: `CAP_SYS_RAWIO
   179  	* Perform I/O port operations (iopl(2) and ioperm(2)).
   180  	* access /proc/kcore.
   181  	* employ the FIBMAP ioctl(2) operation.
   182  	* open devices for accessing x86 model-specific registers (MSRs, see msr(4)).
   183  	* update /proc/sys/vm/mmap_min_addr.
   184  	* create memory mappings at addresses below the value specified by /proc/sys/vm/mmap_min_addr.
   185  	* map files in /proc/bus/pci.
   186  	* open /dev/mem and /dev/kmem.
   187  	* perform various SCSI device commands.
   188  	* perform certain operations on hpsa(4) and cciss(4) devices.
   189  	* perform a range of device-specific operations on other devices.`,
   190  	}
   191  
   192  	capSysChroot = &capability{
   193  		Name:  "CAP_SYS_CHROOT",
   194  		Value: 18,
   195  		Description: `CAP_SYS_CHROOT
   196  	Use chroot(2).`,
   197  	}
   198  
   199  	capSysPtrace = &capability{
   200  		Name:  "CAP_SYS_PTRACE",
   201  		Value: 19,
   202  		Description: `CAP_SYS_PTRACE
   203  	*  Trace arbitrary processes using ptrace(2).
   204  	*  apply get_robust_list(2) to arbitrary processes.
   205  	*  transfer data to or from the memory of arbitrary processes using process_vm_readv(2) and process_vm_writev(2).
   206  	*  inspect processes using kcmp(2).`,
   207  	}
   208  
   209  	capSysPacct = &capability{
   210  		Name:  "CAP_SYS_PACCT",
   211  		Value: 20,
   212  		Description: `CAP_SYS_PACCT
   213  	Use acct(2).`,
   214  	}
   215  
   216  	capSysAdmin = &capability{
   217  		Name:  "CAP_SYS_ADMIN",
   218  		Value: 21,
   219  		Description: `CAP_SYS_ADMIN
   220  	* Perform a range of system administration operations including: quotactl(2), mount(2), umount(2), swapon(2),
   221  	  swapoff(2), sethostname(2), and setdomainname(2).
   222  	* perform privileged syslog(2) operations (since Linux 2.6.37, CAP_SYSLOG should be used to permit such operations).
   223  	* perform VM86_REQUEST_IRQ vm86(2) command.
   224  	* perform IPC_SET and IPC_RMID operations on arbitrary System V IPC objects.
   225  	* override RLIMIT_NPROC resource limit.
   226  	* perform operations on trusted and security Extended Attributes (see xattr(7)).
   227  	* use lookup_dcookie(2).
   228  	* use ioprio_set(2) to assign IOPRIO_CLASS_RT and (before Linux 2.6.25) IOPRIO_CLASS_IDLE I/O scheduling classes.
   229  	* forge PID when passing socket credentials via UNIX domain sockets.
   230  	* exceed /proc/sys/fs/file-max, the system-wide limit on the number of open files, in system calls that open files
   231  	  (e.g., accept(2), execve(2), open(2), pipe(2)).
   232  	* employ CLONE_* flags that create new namespaces with clone(2) and unshare(2) (but, since Linux 3.8, creating user
   233  	  namespaces does not require any capability).
   234  	* call perf_event_open(2).
   235  	* access privileged perf event information.
   236  	* call setns(2) (requires CAP_SYS_ADMIN in the target namespace).
   237  	* call fanotify_init(2).
   238  	* call bpf(2).
   239  	* perform KEYCTL_CHOWN and KEYCTL_SETPERM keyctl(2) operations.
   240  	* perform madvise(2) MADV_HWPOISON operation.
   241  	* employ the TIOCSTI ioctl(2) to insert characters into the input queue of a terminal other than the caller's control‐
   242  	  ling terminal.
   243  	* employ the obsolete nfsservctl(2) system call.
   244  	* employ the obsolete bdflush(2) system call.
   245  	* perform various privileged block-device ioctl(2) operations.
   246  	* perform various privileged filesystem ioctl(2) operations.
   247  	* perform administrative operations on many device drivers.`,
   248  	}
   249  
   250  	capSysBoot = &capability{
   251  		Name:  "CAP_SYS_BOOT",
   252  		Value: 22,
   253  		Description: `CAP_SYS_BOOT
   254  	Use reboot(2) and kexec_load(2).`,
   255  	}
   256  
   257  	capSysNice = &capability{
   258  		Name:  "CAP_SYS_NICE",
   259  		Value: 23,
   260  		Description: `CAP_SYS_NICE
   261  	* Raise process nice value (nice(2), setpriority(2)) and change the nice value for arbitrary processes.
   262  	* set real-time scheduling policies for calling process, and set scheduling policies and priorities for arbitrary
   263  	  processes (sched_setscheduler(2), sched_setparam(2), shed_setattr(2)).
   264  	* set CPU affinity for arbitrary processes (sched_setaffinity(2)).
   265  	* set I/O scheduling class and priority for arbitrary processes (ioprio_set(2)).
   266  	* apply migrate_pages(2) to arbitrary processes and allow processes to be migrated to arbitrary nodes.
   267  	* apply move_pages(2) to arbitrary processes.
   268  	* use the MPOL_MF_MOVE_ALL flag with mbind(2) and move_pages(2).`,
   269  	}
   270  
   271  	capSysResource = &capability{
   272  		Name:  "CAP_SYS_RESOURCE",
   273  		Value: 24,
   274  		Description: `CAP_SYS_RESOURCE
   275  	* Use reserved space on ext2 filesystems.
   276  	* make ioctl(2) calls controlling ext3 journaling.
   277  	* override disk quota limits.
   278  	* increase resource limits (see setrlimit(2)).
   279  	* override RLIMIT_NPROC resource limit.
   280  	* override maximum number of consoles on console allocation.
   281  	* override maximum number of keymaps.
   282  	* allow more than 64hz interrupts from the real-time clock.
   283  	* raise msg_qbytes limit for a System V message queue above the limit in /proc/sys/kernel/msgmnb (see msgop(2) and
   284  	  msgctl(2)).
   285  	* override the /proc/sys/fs/pipe-size-max limit when setting the capacity of a pipe using the F_SETPIPE_SZ fcntl(2)
   286  	  command.
   287  	* use F_SETPIPE_SZ to increase the capacity of a pipe above the limit specified by /proc/sys/fs/pipe-max-size.
   288  	* override /proc/sys/fs/mqueue/queues_max limit when creating POSIX message queues (see mq_overview(7)).
   289  	* employ prctl(2) PR_SET_MM operation.
   290  	* set /proc/PID/oom_score_adj to a value lower than the value last set by a process with CAP_SYS_RESOURCE.`,
   291  	}
   292  
   293  	capSysTime = &capability{
   294  		Name:  "CAP_SYS_TIME",
   295  		Value: 25,
   296  		Description: `CAP_SYS_TIME
   297  	Set system clock (settimeofday(2), stime(2), adjtimex(2)); set real-time (hardware) clock.`,
   298  	}
   299  
   300  	capSysTtyConfig = &capability{
   301  		Name:  "CAP_SYS_TTY_CONFIG",
   302  		Value: 26,
   303  		Description: `CAP_SYS_TTY_CONFIG
   304  	Use vhangup(2); employ various privileged ioctl(2) operations on virtual terminals.`,
   305  	}
   306  
   307  	capMknod = &capability{
   308  		Name:  "CAP_MKNOD",
   309  		Value: 27,
   310  		Description: `CAP_SYS_MKNOD (since Linux 2.4)
   311  	Create special files using mknod(2).`,
   312  	}
   313  
   314  	capLease = &capability{
   315  		Name:  "CAP_LEASE",
   316  		Value: 28,
   317  		Description: `CAP_LEASE (since Linux 2.4)
   318  	Establish leases on arbitrary files (see fcntl(2)).`,
   319  	}
   320  
   321  	capAuditWrite = &capability{
   322  		Name:  "CAP_AUDIT_WRITE",
   323  		Value: 29,
   324  		Description: `CAP_AUDIT_WRITE (since Linux 2.6.11)
   325  	Write records to kernel auditing log.`,
   326  	}
   327  
   328  	capAuditControl = &capability{
   329  		Name:  "CAP_AUDIT_CONTROL",
   330  		Value: 30,
   331  		Description: `CAP_AUDIT_CONTROL (since Linux 2.6.11)
   332  	Enable and disable kernel auditing; change auditing filter rules; retrieve auditing status and filtering rules.`,
   333  	}
   334  
   335  	capSetfcap = &capability{
   336  		Name:  "CAP_SETFCAP",
   337  		Value: 31,
   338  		Description: `CAP_SETFCAP (since Linux 2.6.24)
   339  	Set file capabilities.`,
   340  	}
   341  
   342  	capMacOverride = &capability{
   343  		Name:  "CAP_MAC_OVERRIDE",
   344  		Value: 32,
   345  		Description: `CAP_MAC_OVERRIDE (since Linux 2.6.25)
   346  	Allow MAC configuration or state changes. Implemented for the Smack LSM.`,
   347  	}
   348  
   349  	capMacAdmin = &capability{
   350  		Name:  "CAP_MAC_ADMIN",
   351  		Value: 33,
   352  		Description: `CAP_MAC_ADMIN (since Linux 2.6.25)
   353  	Override Mandatory Access Control (MAC). Implemented for the Smack Linux Security Module (LSM).`,
   354  	}
   355  
   356  	capSyslog = &capability{
   357  		Name:  "CAP_SYSLOG",
   358  		Value: 34,
   359  		Description: `CAP_SYSLOG (since Linux 2.6.37)
   360  	* Perform privileged syslog(2) operations. See syslog(2) for information on which operations require privilege.
   361  	* View kernel addresses exposed via /proc and other interfaces when /proc/sys/kernel/kptr_restrict has the value 1.
   362  	  (See the discussion of the kptr_restrict in proc(5).)`,
   363  	}
   364  
   365  	capWakeAlarm = &capability{
   366  		Name:  "CAP_WAKE_ALARM",
   367  		Value: 35,
   368  		Description: `CAP_WAKE_ALARM (since Linux 3.0)
   369  	Trigger something that will wake up the system (set CLOCK_REALTIME_ALARM and CLOCK_BOOTTIME_ALARM timers).`,
   370  	}
   371  
   372  	capBlockSuspend = &capability{
   373  		Name:  "CAP_WAKE_ALARM",
   374  		Value: 36,
   375  		Description: `CAP_BLOCK_SUSPEND (since Linux 3.5)
   376  	Employ features that can block system suspend (epoll(7) EPOLLWAKEUP, /proc/sys/wake_lock).`,
   377  	}
   378  
   379  	capAuditRead = &capability{
   380  		Name:  "CAP_AUDIT_READ",
   381  		Value: 37,
   382  		Description: `CAP_AUDIT_READ (since Linux 3.16)
   383  	Allow reading the audit log via a multicast netlink socket.`,
   384  	}
   385  )
   386  
   387  // Map maps each capability name to a struct with details about the capability.
   388  var Map = map[string]*capability{
   389  	"CAP_CHOWN":            capChown,
   390  	"CAP_DAC_OVERRIDE":     capDacOverride,
   391  	"CAP_DAC_READ_SEARCH":  capDacReadSearch,
   392  	"CAP_FOWNER":           capFowner,
   393  	"CAP_FSETID":           capFsetid,
   394  	"CAP_KILL":             capKill,
   395  	"CAP_SETGID":           capSetgid,
   396  	"CAP_SETUID":           capSetuid,
   397  	"CAP_SETPCAP":          capSetpcap,
   398  	"CAP_LINUX_IMMUTABLE":  capLinuxImmutable,
   399  	"CAP_NET_BIND_SERVICE": capNetBindService,
   400  	"CAP_NET_BROADCAST":    capNetBroadcast,
   401  	"CAP_NET_ADMIN":        capNetAdmin,
   402  	"CAP_NET_RAW":          capNetRaw,
   403  	"CAP_IPC_LOCK":         capIpcLock,
   404  	"CAP_IPC_OWNER":        capIpcOwner,
   405  	"CAP_SYS_MODULE":       capSysModule,
   406  	"CAP_SYS_RAWIO":        capSysRawio,
   407  	"CAP_SYS_CHROOT":       capSysChroot,
   408  	"CAP_SYS_PTRACE":       capSysPtrace,
   409  	"CAP_SYS_PACCT":        capSysPacct,
   410  	"CAP_SYS_ADMIN":        capSysAdmin,
   411  	"CAP_SYS_BOOT":         capSysBoot,
   412  	"CAP_SYS_NICE":         capSysNice,
   413  	"CAP_SYS_RESOURCE":     capSysResource,
   414  	"CAP_SYS_TIME":         capSysTime,
   415  	"CAP_SYS_TTY_CONFIG":   capSysTtyConfig,
   416  	"CAP_MKNOD":            capMknod,
   417  	"CAP_LEASE":            capLease,
   418  	"CAP_AUDIT_WRITE":      capAuditWrite,
   419  	"CAP_AUDIT_CONTROL":    capAuditControl,
   420  	"CAP_SETFCAP":          capSetfcap,
   421  	"CAP_MAC_OVERRIDE":     capMacOverride,
   422  	"CAP_MAC_ADMIN":        capMacAdmin,
   423  	"CAP_SYSLOG":           capSyslog,
   424  	"CAP_WAKE_ALARM":       capWakeAlarm,
   425  	"CAP_BLOCK_SUSPEND":    capBlockSuspend,
   426  	"CAP_AUDIT_READ":       capAuditRead,
   427  }
   428  
   429  // Normalize takes a slice of capabilities, normalizes and unwraps CAP_ALL.
   430  // The return values are a two slices: normalized capabilities slice that
   431  // are valid and a slice with unrecognized capabilities.
   432  func Normalize(capabilities []string) ([]string, []string) {
   433  	const capAll = "CAP_ALL"
   434  
   435  	capabilities = normalize(capabilities)
   436  
   437  	var included []string
   438  	var excluded []string
   439  	for _, capb := range capabilities {
   440  		if capb == capAll {
   441  			// do not reallocate memory if already did
   442  			// this will NOT panic in case of nil slice
   443  			excluded = excluded[:0]
   444  			included = included[:0]
   445  			for capb := range Map {
   446  				included = append(included, capb)
   447  			}
   448  			break
   449  		}
   450  		if _, ok := Map[capb]; !ok {
   451  			excluded = append(excluded, capb)
   452  			continue
   453  		}
   454  		included = append(included, capb)
   455  	}
   456  
   457  	return RemoveDuplicated(included), RemoveDuplicated(excluded)
   458  }
   459  
   460  // Split takes a list of capabilities separated by commas and
   461  // returns a string list with normalized capability name and a
   462  // second list with unrecognized capabilities.
   463  func Split(caps string) ([]string, []string) {
   464  	if caps == "" {
   465  		return []string{}, []string{}
   466  	}
   467  	return Normalize(strings.Split(caps, ","))
   468  }
   469  
   470  // RemoveDuplicated removes duplicated capabilities from provided list.
   471  // It does not make copy of a passed list.
   472  func RemoveDuplicated(caps []string) []string {
   473  	for i := 0; i < len(caps); i++ {
   474  		for j := i + 1; j < len(caps); j++ {
   475  			if caps[i] == caps[j] {
   476  				caps[j] = caps[len(caps)-1]
   477  				caps = caps[:len(caps)-1]
   478  				j--
   479  			}
   480  		}
   481  	}
   482  	return caps
   483  }
   484  
   485  func normalize(capabilities []string) []string {
   486  	const capPrefix = "CAP_"
   487  	for i, capb := range capabilities {
   488  		capb = strings.TrimSpace(capb)
   489  		capb = strings.ToUpper(capb)
   490  		if !strings.HasPrefix(capb, capPrefix) {
   491  			capb = capPrefix + capb
   492  		}
   493  		capabilities[i] = capb
   494  	}
   495  	return capabilities
   496  }