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

View as plain text