1package cap 2 3import "errors" 4 5// GetFlag determines if the requested Value is enabled in the 6// specified Flag of the capability Set. 7func (c *Set) GetFlag(vec Flag, val Value) (bool, error) { 8 if err := c.good(); err != nil { 9 // Checked this first, because otherwise we are sure 10 // cInit has been called. 11 return false, err 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 err := c.good(); err != nil { 29 // Checked this first, because otherwise we are sure 30 // cInit has been called. 31 return err 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 err := c.good(); err != nil { 66 return err 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// FillFlag copies the from flag values of ref into the to flag of 79// c. With this function, you can raise all of the permitted values in 80// the c Set from those in ref with c.Fill(cap.Permitted, ref, 81// cap.Permitted). 82func (c *Set) FillFlag(to Flag, ref *Set, from Flag) error { 83 if err := c.good(); err != nil { 84 return err 85 } 86 if err := ref.good(); err != nil { 87 return err 88 } 89 if to > Inheritable || from > Inheritable { 90 return ErrBadValue 91 } 92 93 // Avoid deadlock by using a copy. 94 if c != ref { 95 var err error 96 ref, err = ref.Dup() 97 if err != nil { 98 return err 99 } 100 } 101 102 c.mu.Lock() 103 defer c.mu.Unlock() 104 for i := range c.flat { 105 c.flat[i][to] = ref.flat[i][from] 106 } 107 return nil 108} 109 110// Fill copies the from flag values into the to flag. With this 111// function, you can raise all of the permitted values in the 112// effective flag with c.Fill(cap.Effective, cap.Permitted). 113func (c *Set) Fill(to, from Flag) error { 114 return c.FillFlag(to, c, from) 115} 116 117// ErrBadValue indicates a bad capability value was specified. 118var ErrBadValue = errors.New("bad capability value") 119 120// bitOf converts from a Value into the offset and mask for a specific 121// Value bit in the compressed (kernel ABI) representation of a 122// capabilities. If the requested bit is unsupported, an error is 123// returned. 124func bitOf(vec Flag, val Value) (uint, uint32, error) { 125 if vec > Inheritable || val > Value(words*32) { 126 return 0, 0, ErrBadValue 127 } 128 u := uint(val) 129 return u / 32, uint32(1) << (u % 32), nil 130} 131 132// allMask returns the mask of valid bits in the all mask for index. 133func allMask(index uint) (mask uint32) { 134 if maxValues == 0 { 135 panic("uninitialized package") 136 } 137 base := 32 * uint(index) 138 if maxValues <= base { 139 return 140 } 141 if maxValues >= 32+base { 142 mask = ^mask 143 return 144 } 145 mask = uint32((uint64(1) << (maxValues % 32)) - 1) 146 return 147} 148 149// forceFlag sets 'all' capability values (supported by the kernel) of 150// a specified Flag to enable. 151func (c *Set) forceFlag(vec Flag, enable bool) error { 152 if err := c.good(); err != nil { 153 return err 154 } 155 if vec > Inheritable { 156 return ErrBadSet 157 } 158 m := uint32(0) 159 if enable { 160 m = ^m 161 } 162 c.mu.Lock() 163 defer c.mu.Unlock() 164 for i := range c.flat { 165 c.flat[i][vec] = m & allMask(uint(i)) 166 } 167 return nil 168} 169 170// ClearFlag clears all the Values associated with the specified Flag. 171func (c *Set) ClearFlag(vec Flag) error { 172 return c.forceFlag(vec, false) 173} 174 175// Cf returns 0 if c and d are identical. A non-zero Diff value 176// captures a simple macroscopic summary of how they differ. The 177// (Diff).Has() function can be used to determine how the two 178// capability sets differ. 179func (c *Set) Cf(d *Set) (Diff, error) { 180 if err := c.good(); err != nil { 181 return 0, err 182 } 183 if c == d { 184 return 0, nil 185 } 186 d, err := d.Dup() 187 if err != nil { 188 return 0, err 189 } 190 191 c.mu.RLock() 192 defer c.mu.RUnlock() 193 194 var cf Diff 195 for i := 0; i < words; i++ { 196 if c.flat[i][Effective]^d.flat[i][Effective] != 0 { 197 cf |= effectiveDiff 198 } 199 if c.flat[i][Permitted]^d.flat[i][Permitted] != 0 { 200 cf |= permittedDiff 201 } 202 if c.flat[i][Inheritable]^d.flat[i][Inheritable] != 0 { 203 cf |= inheritableDiff 204 } 205 } 206 return cf, nil 207} 208 209// Compare returns 0 if c and d are identical in content. 210// 211// Deprecated: Replace with (*Set).Cf(). 212// 213// Example, replace this: 214// 215// diff, err := a.Compare(b) 216// if err != nil { 217// return err 218// } 219// if diff == 0 { 220// return nil 221// } 222// if diff & (1 << Effective) { 223// log.Print("a and b difference includes Effective values") 224// } 225// 226// with this: 227// 228// diff, err := a.Cf(b) 229// if err != nil { 230// return err 231// } 232// if diff == 0 { 233// return nil 234// } 235// if diff.Has(Effective) { 236// log.Print("a and b difference includes Effective values") 237// } 238func (c *Set) Compare(d *Set) (uint, error) { 239 u, err := c.Cf(d) 240 return uint(u), err 241} 242 243// Differs processes the result of Compare and determines if the 244// Flag's components were different. 245// 246// Deprecated: Replace with (Diff).Has(). 247// 248// Example, replace this: 249// 250// diff, err := a.Compare(b) 251// ... 252// if diff & (1 << Effective) { 253// ... different effective capabilities ... 254// } 255// 256// with this: 257// 258// diff, err := a.Cf(b) 259// ... 260// if diff.Has(Effective) { 261// ... different effective capabilities ... 262// } 263func Differs(cf uint, vec Flag) bool { 264 return cf&(1<<vec) != 0 265} 266 267// Has processes the Diff result of (*Set).Cf() and determines if the 268// Flag's components were different in that result. 269func (cf Diff) Has(vec Flag) bool { 270 return uint(cf)&(1<<vec) != 0 271} 272