xref: /aosp_15_r20/external/libcap/libcap/cap_test.c (revision 2810ac1b38eead2603277920c78344c84ddf3aff)
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