Mercurial > yakumo_izuru > aya
comparison vendor/golang.org/x/sys/unix/cap_freebsd.go @ 66:787b5ee0289d draft
Use vendored modules
Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author | yakumo.izuru |
---|---|
date | Sun, 23 Jul 2023 13:18:53 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
65:6d985efa0f7a | 66:787b5ee0289d |
---|---|
1 // Copyright 2017 The Go Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style | |
3 // license that can be found in the LICENSE file. | |
4 | |
5 //go:build freebsd | |
6 // +build freebsd | |
7 | |
8 package unix | |
9 | |
10 import ( | |
11 "errors" | |
12 "fmt" | |
13 ) | |
14 | |
15 // Go implementation of C mostly found in /usr/src/sys/kern/subr_capability.c | |
16 | |
17 const ( | |
18 // This is the version of CapRights this package understands. See C implementation for parallels. | |
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 // CapRightsSet sets the permissions in setrights in rights. | |
56 func CapRightsSet(rights *CapRights, setrights []uint64) error { | |
57 // This is essentially a copy of cap_rights_vset() | |
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 // CapRightsClear clears the permissions in clearrights from rights. | |
91 func CapRightsClear(rights *CapRights, clearrights []uint64) error { | |
92 // This is essentially a copy of cap_rights_vclear() | |
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 // CapRightsIsSet checks whether all the permissions in setrights are present in rights. | |
126 func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) { | |
127 // This is essentially a copy of cap_rights_is_vset() | |
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 // CapRightsInit returns a pointer to an initialised CapRights structure filled with rights. | |
164 // See man cap_rights_init(3) and rights(4). | |
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 // CapRightsLimit reduces the operations permitted on fd to at most those contained in rights. | |
178 // The capability rights on fd can never be increased by CapRightsLimit. | |
179 // See man cap_rights_limit(2) and rights(4). | |
180 func CapRightsLimit(fd uintptr, rights *CapRights) error { | |
181 return capRightsLimit(int(fd), rights) | |
182 } | |
183 | |
184 // CapRightsGet returns a CapRights structure containing the operations permitted on fd. | |
185 // See man cap_rights_get(3) and rights(4). | |
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 } |