• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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// Fill copies the from flag values into the to flag. With this
79// function, you can raise all of the permitted values in the
80// effective flag with c.Fill(cap.Effective, cap.Permitted).
81func (c *Set) Fill(to, from Flag) error {
82	if c == nil || len(c.flat) == 0 {
83		return ErrBadSet
84	}
85	if to > Inheritable || from > Inheritable {
86		return ErrBadValue
87	}
88	c.mu.Lock()
89	defer c.mu.Unlock()
90	for i := range c.flat {
91		c.flat[i][to] = c.flat[i][from]
92	}
93	return nil
94}
95
96// ErrBadValue indicates a bad capability value was specified.
97var ErrBadValue = errors.New("bad capability value")
98
99// bitOf converts from a Value into the offset and mask for a
100// specific Value bit in the compressed (kernel ABI) representation of
101// a capability vector. If the requested bit is unsupported, an error
102// is returned.
103func bitOf(vec Flag, val Value) (uint, uint32, error) {
104	if vec > Inheritable || val > Value(words*32) {
105		return 0, 0, ErrBadValue
106	}
107	u := uint(val)
108	return u / 32, uint32(1) << (u % 32), nil
109}
110
111// allMask returns the mask of valid bits in the all mask for index.
112func allMask(index uint) (mask uint32) {
113	if maxValues == 0 {
114		panic("uninitialized package")
115	}
116	base := 32 * uint(index)
117	if maxValues <= base {
118		return
119	}
120	if maxValues >= 32+base {
121		mask = ^mask
122		return
123	}
124	mask = uint32((uint64(1) << (maxValues % 32)) - 1)
125	return
126}
127
128// forceFlag sets 'all' capability values (supported by the kernel) of
129// a flag vector to enable.
130func (c *Set) forceFlag(vec Flag, enable bool) error {
131	if c == nil || len(c.flat) == 0 || vec > Inheritable {
132		return ErrBadSet
133	}
134	m := uint32(0)
135	if enable {
136		m = ^m
137	}
138	c.mu.Lock()
139	defer c.mu.Unlock()
140	for i := range c.flat {
141		c.flat[i][vec] = m & allMask(uint(i))
142	}
143	return nil
144}
145
146// ClearFlag clears a specific vector of Values associated with the
147// specified Flag.
148func (c *Set) ClearFlag(vec Flag) error {
149	return c.forceFlag(vec, false)
150}
151
152// Compare returns 0 if c and d are identical in content. Otherwise,
153// this function returns a non-zero value of 3 independent bits:
154// (differE ? 1:0) | (differP ? 2:0) | (differI ? 4:0). The Differs()
155// function can be used to test for a difference in a specific Flag.
156func (c *Set) Compare(d *Set) (uint, error) {
157	if c == nil || len(c.flat) == 0 || d == nil || len(d.flat) == 0 {
158		return 0, ErrBadSet
159	}
160	var cf uint
161	for i := 0; i < words; i++ {
162		if c.flat[i][Effective]^d.flat[i][Effective] != 0 {
163			cf |= (1 << Effective)
164		}
165		if c.flat[i][Permitted]^d.flat[i][Permitted] != 0 {
166			cf |= (1 << Permitted)
167		}
168		if c.flat[i][Inheritable]^d.flat[i][Inheritable] != 0 {
169			cf |= (1 << Inheritable)
170		}
171	}
172	return cf, nil
173}
174
175// Differs processes the result of Compare and determines if the
176// Flag's components were different.
177func Differs(cf uint, vec Flag) bool {
178	return cf&(1<<vec) != 0
179}
180