1package cap 2 3import "errors" 4 5// GetFlag determines if the requested bit is enabled in the Flag 6// vector of the capability Set. 7func (c *Set) GetFlag(vec Flag, val Value) (bool, error) { 8 if c == nil || len(c.flat) == 0 { 9 // Checked this first, because otherwise we are sure 10 // cInit has been called. 11 return false, ErrBadSet 12 } 13 offset, mask, err := bitOf(vec, val) 14 if err != nil { 15 return false, err 16 } 17 c.mu.RLock() 18 defer c.mu.RUnlock() 19 return c.flat[offset][vec]&mask != 0, nil 20} 21 22// SetFlag sets the requested bits to the indicated enable state. This 23// function does not perform any security checks, so values can be set 24// out-of-order. Only when the Set is used to SetProc() etc., will the 25// bits be checked for validity and permission by the kernel. If the 26// function returns an error, the Set will not be modified. 27func (c *Set) SetFlag(vec Flag, enable bool, val ...Value) error { 28 if c == nil || len(c.flat) == 0 { 29 // Checked this first, because otherwise we are sure 30 // cInit has been called. 31 return ErrBadSet 32 } 33 c.mu.Lock() 34 defer c.mu.Unlock() 35 // Make a backup. 36 replace := make([]uint32, words) 37 for i := range replace { 38 replace[i] = c.flat[i][vec] 39 } 40 var err error 41 for _, v := range val { 42 offset, mask, err2 := bitOf(vec, v) 43 if err2 != nil { 44 err = err2 45 break 46 } 47 if enable { 48 c.flat[offset][vec] |= mask 49 } else { 50 c.flat[offset][vec] &= ^mask 51 } 52 } 53 if err == nil { 54 return nil 55 } 56 // Clean up. 57 for i, bits := range replace { 58 c.flat[i][vec] = bits 59 } 60 return err 61} 62 63// Clear fully clears a capability set. 64func (c *Set) Clear() error { 65 if c == nil || len(c.flat) == 0 { 66 return ErrBadSet 67 } 68 // startUp.Do(cInit) is not called here because c cannot be 69 // initialized except via this package and doing that will 70 // perform that call at least once (sic). 71 c.mu.Lock() 72 defer c.mu.Unlock() 73 c.flat = make([]data, words) 74 c.nsRoot = 0 75 return nil 76} 77 78// ErrBadValue indicates a bad capability value was specified. 79var ErrBadValue = errors.New("bad capability value") 80 81// bitOf converts from a Value into the offset and mask for a 82// specific Value bit in the compressed (kernel ABI) representation of 83// a capability vector. If the requested bit is unsupported, an error 84// is returned. 85func bitOf(vec Flag, val Value) (uint, uint32, error) { 86 if vec > Inheritable || val > Value(words*32) { 87 return 0, 0, ErrBadValue 88 } 89 u := uint(val) 90 return u / 32, uint32(1) << (u % 32), nil 91} 92 93// allMask returns the mask of valid bits in the all mask for index. 94func allMask(index uint) (mask uint32) { 95 if maxValues == 0 { 96 panic("uninitialized package") 97 } 98 base := 32 * uint(index) 99 if maxValues <= base { 100 return 101 } 102 if maxValues >= 32+base { 103 mask = ^mask 104 return 105 } 106 mask = uint32((uint64(1) << (maxValues % 32)) - 1) 107 return 108} 109 110// forceFlag sets 'all' capability values (supported by the kernel) of 111// a flag vector to enable. 112func (c *Set) forceFlag(vec Flag, enable bool) error { 113 if c == nil || len(c.flat) == 0 || vec > Inheritable { 114 return ErrBadSet 115 } 116 m := uint32(0) 117 if enable { 118 m = ^m 119 } 120 c.mu.Lock() 121 defer c.mu.Unlock() 122 for i := range c.flat { 123 c.flat[i][vec] = m & allMask(uint(i)) 124 } 125 return nil 126} 127 128// ClearFlag clears a specific vector of Values associated with the 129// specified Flag. 130func (c *Set) ClearFlag(vec Flag) error { 131 return c.forceFlag(vec, false) 132} 133 134// Compare returns 0 if c and d are identical in content. Otherwise, 135// this function returns a non-zero value of 3 independent bits: 136// (differE ? 1:0) | (differP ? 2:0) | (differI ? 4:0). The Differs() 137// function can be used to test for a difference in a specific Flag. 138func (c *Set) Compare(d *Set) (uint, error) { 139 if c == nil || len(c.flat) == 0 || d == nil || len(d.flat) == 0 { 140 return 0, ErrBadSet 141 } 142 var cf uint 143 for i := 0; i < words; i++ { 144 if c.flat[i][Effective]^d.flat[i][Effective] != 0 { 145 cf |= (1 << Effective) 146 } 147 if c.flat[i][Permitted]^d.flat[i][Permitted] != 0 { 148 cf |= (1 << Permitted) 149 } 150 if c.flat[i][Inheritable]^d.flat[i][Inheritable] != 0 { 151 cf |= (1 << Inheritable) 152 } 153 } 154 return cf, nil 155} 156 157// Differs processes the result of Compare and determines if the 158// Flag's components were different. 159func Differs(cf uint, vec Flag) bool { 160 return cf&(1<<vec) != 0 161} 162