Path: blob/main/vendor/golang.org/x/sys/unix/cap_freebsd.go
2880 views
// Copyright 2017 The Go Authors. All rights reserved.1// Use of this source code is governed by a BSD-style2// license that can be found in the LICENSE file.34//go:build freebsd56package unix78import (9"errors"10"fmt"11)1213// Go implementation of C mostly found in /usr/src/sys/kern/subr_capability.c1415const (16// This is the version of CapRights this package understands. See C implementation for parallels.17capRightsGoVersion = CAP_RIGHTS_VERSION_0018capArSizeMin = CAP_RIGHTS_VERSION_00 + 219capArSizeMax = capRightsGoVersion + 220)2122var (23bit2idx = []int{24-1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,254, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,26}27)2829func capidxbit(right uint64) int {30return int((right >> 57) & 0x1f)31}3233func rightToIndex(right uint64) (int, error) {34idx := capidxbit(right)35if idx < 0 || idx >= len(bit2idx) {36return -2, fmt.Errorf("index for right 0x%x out of range", right)37}38return bit2idx[idx], nil39}4041func caprver(right uint64) int {42return int(right >> 62)43}4445func capver(rights *CapRights) int {46return caprver(rights.Rights[0])47}4849func caparsize(rights *CapRights) int {50return capver(rights) + 251}5253// CapRightsSet sets the permissions in setrights in rights.54func CapRightsSet(rights *CapRights, setrights []uint64) error {55// This is essentially a copy of cap_rights_vset()56if capver(rights) != CAP_RIGHTS_VERSION_00 {57return fmt.Errorf("bad rights version %d", capver(rights))58}5960n := caparsize(rights)61if n < capArSizeMin || n > capArSizeMax {62return errors.New("bad rights size")63}6465for _, right := range setrights {66if caprver(right) != CAP_RIGHTS_VERSION_00 {67return errors.New("bad right version")68}69i, err := rightToIndex(right)70if err != nil {71return err72}73if i >= n {74return errors.New("index overflow")75}76if capidxbit(rights.Rights[i]) != capidxbit(right) {77return errors.New("index mismatch")78}79rights.Rights[i] |= right80if capidxbit(rights.Rights[i]) != capidxbit(right) {81return errors.New("index mismatch (after assign)")82}83}8485return nil86}8788// CapRightsClear clears the permissions in clearrights from rights.89func CapRightsClear(rights *CapRights, clearrights []uint64) error {90// This is essentially a copy of cap_rights_vclear()91if capver(rights) != CAP_RIGHTS_VERSION_00 {92return fmt.Errorf("bad rights version %d", capver(rights))93}9495n := caparsize(rights)96if n < capArSizeMin || n > capArSizeMax {97return errors.New("bad rights size")98}99100for _, right := range clearrights {101if caprver(right) != CAP_RIGHTS_VERSION_00 {102return errors.New("bad right version")103}104i, err := rightToIndex(right)105if err != nil {106return err107}108if i >= n {109return errors.New("index overflow")110}111if capidxbit(rights.Rights[i]) != capidxbit(right) {112return errors.New("index mismatch")113}114rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF)115if capidxbit(rights.Rights[i]) != capidxbit(right) {116return errors.New("index mismatch (after assign)")117}118}119120return nil121}122123// CapRightsIsSet checks whether all the permissions in setrights are present in rights.124func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) {125// This is essentially a copy of cap_rights_is_vset()126if capver(rights) != CAP_RIGHTS_VERSION_00 {127return false, fmt.Errorf("bad rights version %d", capver(rights))128}129130n := caparsize(rights)131if n < capArSizeMin || n > capArSizeMax {132return false, errors.New("bad rights size")133}134135for _, right := range setrights {136if caprver(right) != CAP_RIGHTS_VERSION_00 {137return false, errors.New("bad right version")138}139i, err := rightToIndex(right)140if err != nil {141return false, err142}143if i >= n {144return false, errors.New("index overflow")145}146if capidxbit(rights.Rights[i]) != capidxbit(right) {147return false, errors.New("index mismatch")148}149if (rights.Rights[i] & right) != right {150return false, nil151}152}153154return true, nil155}156157func capright(idx uint64, bit uint64) uint64 {158return ((1 << (57 + idx)) | bit)159}160161// CapRightsInit returns a pointer to an initialised CapRights structure filled with rights.162// See man cap_rights_init(3) and rights(4).163func CapRightsInit(rights []uint64) (*CapRights, error) {164var r CapRights165r.Rights[0] = (capRightsGoVersion << 62) | capright(0, 0)166r.Rights[1] = capright(1, 0)167168err := CapRightsSet(&r, rights)169if err != nil {170return nil, err171}172return &r, nil173}174175// CapRightsLimit reduces the operations permitted on fd to at most those contained in rights.176// The capability rights on fd can never be increased by CapRightsLimit.177// See man cap_rights_limit(2) and rights(4).178func CapRightsLimit(fd uintptr, rights *CapRights) error {179return capRightsLimit(int(fd), rights)180}181182// CapRightsGet returns a CapRights structure containing the operations permitted on fd.183// See man cap_rights_get(3) and rights(4).184func CapRightsGet(fd uintptr) (*CapRights, error) {185r, err := CapRightsInit(nil)186if err != nil {187return nil, err188}189err = capRightsGet(capRightsGoVersion, int(fd), r)190if err != nil {191return nil, err192}193return r, nil194}195196197