1 #define _GNU_SOURCE
2 #include <stdio.h>
3
4 #include "libcap.h"
5
6 static cap_value_t top;
7
cf(cap_value_t x)8 static int cf(cap_value_t x)
9 {
10 return top - x - 1;
11 }
12
test_cap_bits(void)13 static int test_cap_bits(void)
14 {
15 static cap_value_t vs[] = {
16 5, 6, 11, 12, 15, 16, 17, 38, 41, 63, 64, __CAP_MAXBITS+3, 0, -1
17 };
18 int failed = 0;
19 cap_value_t i;
20 for (i = 0; vs[i] >= 0; i++) {
21 cap_value_t ans;
22
23 top = vs[i];
24 _binary_search(ans, cf, 0, __CAP_MAXBITS, -1);
25 if (ans != top) {
26 if (top == 0 && ans == -1) {
27 continue;
28 }
29 if (top > __CAP_MAXBITS && ans == -1) {
30 continue;
31 }
32 printf("test_cap_bits miscompared [%d] top=%d - got=%d\n",
33 i, top, ans);
34 failed = -1;
35 }
36 }
37 return failed;
38 }
39
test_cap_flags(void)40 static int test_cap_flags(void)
41 {
42 cap_t c, d;
43 cap_flag_t f = CAP_INHERITABLE, t;
44 cap_value_t v;
45 int retval = 0;
46
47 c = cap_init();
48 if (c == NULL) {
49 printf("test_flags failed to allocate a set\n");
50 return -1;
51 }
52 if (cap_compare(c, NULL) != -1) {
53 printf("compare to NULL should give invalid\n");
54 return -1;
55 }
56 if (cap_compare(NULL, c) != -1) {
57 printf("compare with NULL should give invalid\n");
58 return -1;
59 }
60
61 for (v = 0; v < __CAP_MAXBITS; v += 3) {
62 if (cap_set_flag(c, CAP_INHERITABLE, 1, &v, CAP_SET)) {
63 printf("unable to set inheritable bit %d\n", v);
64 retval = -1;
65 goto drop_c;
66 }
67 }
68
69 d = cap_dup(c);
70 for (t = CAP_EFFECTIVE; t <= CAP_INHERITABLE; t++) {
71 if (cap_fill(c, t, f)) {
72 printf("cap_fill failed %d -> %d\n", f, t);
73 retval = -1;
74 goto drop_d;
75 }
76 if (cap_clear_flag(c, f)) {
77 printf("cap_fill unable to clear flag %d\n", f);
78 retval = -1;
79 goto drop_d;
80 }
81 f = t;
82 }
83 if (cap_compare(c, d)) {
84 printf("permuted cap_fill()ing failed to perform net no-op\n");
85 retval = -1;
86 }
87 if (cap_fill_flag(NULL, CAP_EFFECTIVE, c, CAP_INHERITABLE) == 0) {
88 printf("filling NULL flag should fail\n");
89 retval = -1;
90 }
91 if (cap_fill_flag(d, CAP_PERMITTED, c, CAP_INHERITABLE) != 0) {
92 perror("filling PERMITEED flag should work");
93 retval = -1;
94 }
95 if (cap_fill_flag(c, CAP_PERMITTED, d, CAP_PERMITTED) != 0) {
96 perror("filling PERMITTED flag from another cap_t should work");
97 retval = -1;
98 }
99 if (cap_compare(c, d)) {
100 printf("permuted cap_fill()ing failed to perform net no-op\n");
101 retval = -1;
102 }
103
104 drop_d:
105 if (cap_free(d) != 0) {
106 perror("failed to free d");
107 retval = -1;
108 }
109 drop_c:
110 if (cap_free(c) != 0) {
111 perror("failed to free c");
112 retval = -1;
113 }
114 return retval;
115 }
116
test_short_bits(void)117 static int test_short_bits(void)
118 {
119 int result = 0;
120 char *tmp;
121 int n = asprintf(&tmp, "%d", __CAP_MAXBITS);
122 if (n <= 0) {
123 return -1;
124 }
125 if (strlen(tmp) > __CAP_NAME_SIZE) {
126 printf("cap_to_text buffer size reservation needs fixing (%ld > %d)\n",
127 (long int)strlen(tmp), __CAP_NAME_SIZE);
128 result = -1;
129 }
130 free(tmp);
131 return result;
132 }
133
noop(void * data)134 static int noop(void *data)
135 {
136 return -1;
137 }
138
test_alloc(void)139 static int test_alloc(void)
140 {
141 int retval = 0;
142 cap_t c;
143 cap_iab_t iab;
144 cap_launch_t launcher;
145 char *old_root;
146
147 printf("test_alloc\n");
148 fflush(stdout);
149
150 c = cap_init();
151 if (c == NULL) {
152 perror("failed to allocate a cap_t");
153 fflush(stderr);
154 return -1;
155 }
156
157 iab = cap_iab_init();
158 if (iab == NULL) {
159 perror("failed to allocate a cap_iab_t");
160 fflush(stderr);
161 retval = -1;
162 goto drop_c;
163 }
164
165 launcher = cap_func_launcher(noop);
166 if (launcher == NULL) {
167 perror("failde to allocate a launcher");
168 fflush(stderr);
169 retval = -1;
170 goto drop_iab;
171 }
172
173 cap_launcher_set_chroot(launcher, "/tmp");
174 if (cap_launcher_set_iab(launcher, iab) != NULL) {
175 printf("unable to replace iab in launcher\n");
176 fflush(stdout);
177 retval = -1;
178 goto drop_iab;
179 }
180
181 iab = cap_launcher_set_iab(launcher, cap_iab_init());
182 if (iab == NULL) {
183 printf("unable to recover iab in launcher\n");
184 fflush(stdout);
185 retval = -1;
186 goto drop_launcher;
187 }
188
189 old_root = cap_proc_root("blah");
190 if (old_root != NULL) {
191 printf("bad initial proc_root [%s]\n", old_root);
192 fflush(stdout);
193 retval = -1;
194 }
195 if (cap_free(old_root)) {
196 perror("unable to free old proc root");
197 fflush(stderr);
198 retval = -1;
199 }
200 if (retval) {
201 goto drop_launcher;
202 }
203 old_root = cap_proc_root("/proc");
204 if (strcmp(old_root, "blah") != 0) {
205 printf("bad proc_root value [%s]\n", old_root);
206 fflush(stdout);
207 retval = -1;
208 }
209 if (cap_free(old_root)) {
210 perror("unable to free replacement proc root");
211 fflush(stderr);
212 retval = -1;
213 }
214 if (retval) {
215 goto drop_launcher;
216 }
217
218 drop_launcher:
219 printf("test_alloc: drop_launcher\n");
220 fflush(stdout);
221 if (cap_free(launcher)) {
222 perror("failed to free launcher");
223 fflush(stderr);
224 retval = -1;
225 }
226
227 drop_iab:
228 printf("test_alloc: drop_iab\n");
229 fflush(stdout);
230 if (!cap_free(2+(__u32 *) iab)) {
231 printf("unable to recognize bad cap_iab_t pointer\n");
232 fflush(stdout);
233 retval = -1;
234 }
235 if (cap_free(iab)) {
236 perror("failed to free iab");
237 fflush(stderr);
238 retval = -1;
239 }
240
241 drop_c:
242 printf("test_alloc: drop_cap\n");
243 fflush(stdout);
244 if (!cap_free(1+(__u32 *) c)) {
245 printf("unable to recognize bad cap_t pointer\n");
246 fflush(stdout);
247 retval = -1;
248 }
249 if (cap_free(c)) {
250 perror("failed to free c");
251 fflush(stderr);
252 retval = -1;
253 }
254 return retval;
255 }
256
test_prctl(void)257 static int test_prctl(void)
258 {
259 int ret, retval=0;
260 errno = 0;
261 ret = cap_get_bound((cap_value_t) -1);
262 if (ret != -1) {
263 printf("cap_get_bound(-1) did not return error: %d\n", ret);
264 retval = -1;
265 } else if (errno != EINVAL) {
266 perror("cap_get_bound(-1) errno != EINVAL");
267 retval = -1;
268 }
269 return retval;
270 }
271
main(int argc,char ** argv)272 int main(int argc, char **argv) {
273 int result = 0;
274
275 printf("test_cap_bits: being called\n");
276 fflush(stdout);
277 result = test_cap_bits() | result;
278 printf("test_cap_flags: being called\n");
279 fflush(stdout);
280 result = test_cap_flags() | result;
281 printf("test_short_bits: being called\n");
282 fflush(stdout);
283 result = test_short_bits() | result;
284 printf("test_alloc: being called\n");
285 fflush(stdout);
286 result = test_alloc() | result;
287 printf("test_prctl: being called\n");
288 fflush(stdout);
289 result = test_prctl() | result;
290 printf("tested\n");
291 fflush(stdout);
292
293 if (result) {
294 printf("cap_test FAILED\n");
295 exit(1);
296 }
297 printf("cap_test PASS\n");
298 exit(0);
299 }
300