1
2
3
4
5
6
7
8 package unix
9
10 import (
11 "errors"
12 "fmt"
13 )
14
15
16
17 const (
18
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
56 func CapRightsSet(rights *CapRights, setrights []uint64) error {
57
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
91 func CapRightsClear(rights *CapRights, clearrights []uint64) error {
92
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
126 func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) {
127
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
164
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
178
179
180 func CapRightsLimit(fd uintptr, rights *CapRights) error {
181 return capRightsLimit(int(fd), rights)
182 }
183
184
185
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