...

Source file src/pkg/cmd/vendor/golang.org/x/sys/unix/cap_freebsd.go

     1	// Copyright 2017 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// +build freebsd
     6	
     7	package unix
     8	
     9	import (
    10		"errors"
    11		"fmt"
    12	)
    13	
    14	// Go implementation of C mostly found in /usr/src/sys/kern/subr_capability.c
    15	
    16	const (
    17		// This is the version of CapRights this package understands. See C implementation for parallels.
    18		capRightsGoVersion = CAP_RIGHTS_VERSION_00
    19		capArSizeMin       = CAP_RIGHTS_VERSION_00 + 2
    20		capArSizeMax       = capRightsGoVersion + 2
    21	)
    22	
    23	var (
    24		bit2idx = []int{
    25			-1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,
    26			4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    27		}
    28	)
    29	
    30	func capidxbit(right uint64) int {
    31		return int((right >> 57) & 0x1f)
    32	}
    33	
    34	func rightToIndex(right uint64) (int, error) {
    35		idx := capidxbit(right)
    36		if idx < 0 || idx >= len(bit2idx) {
    37			return -2, fmt.Errorf("index for right 0x%x out of range", right)
    38		}
    39		return bit2idx[idx], nil
    40	}
    41	
    42	func caprver(right uint64) int {
    43		return int(right >> 62)
    44	}
    45	
    46	func capver(rights *CapRights) int {
    47		return caprver(rights.Rights[0])
    48	}
    49	
    50	func caparsize(rights *CapRights) int {
    51		return capver(rights) + 2
    52	}
    53	
    54	// CapRightsSet sets the permissions in setrights in rights.
    55	func CapRightsSet(rights *CapRights, setrights []uint64) error {
    56		// This is essentially a copy of cap_rights_vset()
    57		if capver(rights) != CAP_RIGHTS_VERSION_00 {
    58			return fmt.Errorf("bad rights version %d", capver(rights))
    59		}
    60	
    61		n := caparsize(rights)
    62		if n < capArSizeMin || n > capArSizeMax {
    63			return errors.New("bad rights size")
    64		}
    65	
    66		for _, right := range setrights {
    67			if caprver(right) != CAP_RIGHTS_VERSION_00 {
    68				return errors.New("bad right version")
    69			}
    70			i, err := rightToIndex(right)
    71			if err != nil {
    72				return err
    73			}
    74			if i >= n {
    75				return errors.New("index overflow")
    76			}
    77			if capidxbit(rights.Rights[i]) != capidxbit(right) {
    78				return errors.New("index mismatch")
    79			}
    80			rights.Rights[i] |= right
    81			if capidxbit(rights.Rights[i]) != capidxbit(right) {
    82				return errors.New("index mismatch (after assign)")
    83			}
    84		}
    85	
    86		return nil
    87	}
    88	
    89	// CapRightsClear clears the permissions in clearrights from rights.
    90	func CapRightsClear(rights *CapRights, clearrights []uint64) error {
    91		// This is essentially a copy of cap_rights_vclear()
    92		if capver(rights) != CAP_RIGHTS_VERSION_00 {
    93			return fmt.Errorf("bad rights version %d", capver(rights))
    94		}
    95	
    96		n := caparsize(rights)
    97		if n < capArSizeMin || n > capArSizeMax {
    98			return errors.New("bad rights size")
    99		}
   100	
   101		for _, right := range clearrights {
   102			if caprver(right) != CAP_RIGHTS_VERSION_00 {
   103				return errors.New("bad right version")
   104			}
   105			i, err := rightToIndex(right)
   106			if err != nil {
   107				return err
   108			}
   109			if i >= n {
   110				return errors.New("index overflow")
   111			}
   112			if capidxbit(rights.Rights[i]) != capidxbit(right) {
   113				return errors.New("index mismatch")
   114			}
   115			rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF)
   116			if capidxbit(rights.Rights[i]) != capidxbit(right) {
   117				return errors.New("index mismatch (after assign)")
   118			}
   119		}
   120	
   121		return nil
   122	}
   123	
   124	// CapRightsIsSet checks whether all the permissions in setrights are present in rights.
   125	func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) {
   126		// This is essentially a copy of cap_rights_is_vset()
   127		if capver(rights) != CAP_RIGHTS_VERSION_00 {
   128			return false, fmt.Errorf("bad rights version %d", capver(rights))
   129		}
   130	
   131		n := caparsize(rights)
   132		if n < capArSizeMin || n > capArSizeMax {
   133			return false, errors.New("bad rights size")
   134		}
   135	
   136		for _, right := range setrights {
   137			if caprver(right) != CAP_RIGHTS_VERSION_00 {
   138				return false, errors.New("bad right version")
   139			}
   140			i, err := rightToIndex(right)
   141			if err != nil {
   142				return false, err
   143			}
   144			if i >= n {
   145				return false, errors.New("index overflow")
   146			}
   147			if capidxbit(rights.Rights[i]) != capidxbit(right) {
   148				return false, errors.New("index mismatch")
   149			}
   150			if (rights.Rights[i] & right) != right {
   151				return false, nil
   152			}
   153		}
   154	
   155		return true, nil
   156	}
   157	
   158	func capright(idx uint64, bit uint64) uint64 {
   159		return ((1 << (57 + idx)) | bit)
   160	}
   161	
   162	// CapRightsInit returns a pointer to an initialised CapRights structure filled with rights.
   163	// See man cap_rights_init(3) and rights(4).
   164	func CapRightsInit(rights []uint64) (*CapRights, error) {
   165		var r CapRights
   166		r.Rights[0] = (capRightsGoVersion << 62) | capright(0, 0)
   167		r.Rights[1] = capright(1, 0)
   168	
   169		err := CapRightsSet(&r, rights)
   170		if err != nil {
   171			return nil, err
   172		}
   173		return &r, nil
   174	}
   175	
   176	// CapRightsLimit reduces the operations permitted on fd to at most those contained in rights.
   177	// The capability rights on fd can never be increased by CapRightsLimit.
   178	// See man cap_rights_limit(2) and rights(4).
   179	func CapRightsLimit(fd uintptr, rights *CapRights) error {
   180		return capRightsLimit(int(fd), rights)
   181	}
   182	
   183	// CapRightsGet returns a CapRights structure containing the operations permitted on fd.
   184	// See man cap_rights_get(3) and rights(4).
   185	func CapRightsGet(fd uintptr) (*CapRights, error) {
   186		r, err := CapRightsInit(nil)
   187		if err != nil {
   188			return nil, err
   189		}
   190		err = capRightsGet(capRightsGoVersion, int(fd), r)
   191		if err != nil {
   192			return nil, err
   193		}
   194		return r, nil
   195	}
   196	

View as plain text