xref: /aosp_15_r20/external/libcap-ng/src/test/lib_test.c (revision 8dd5e09d5faf27a871e8654ddaa2d2af7c696578)
1*8dd5e09dSSadaf Ebrahimi /* lib_test.c -- simple libcap-ng test suite
2*8dd5e09dSSadaf Ebrahimi  * Copyright 2009,2012-13 Red Hat Inc.
3*8dd5e09dSSadaf Ebrahimi  * All Rights Reserved.
4*8dd5e09dSSadaf Ebrahimi  *
5*8dd5e09dSSadaf Ebrahimi  * This library is free software; you can redistribute it and/or
6*8dd5e09dSSadaf Ebrahimi  * modify it under the terms of the GNU Lesser General Public
7*8dd5e09dSSadaf Ebrahimi  * License as published by the Free Software Foundation; either
8*8dd5e09dSSadaf Ebrahimi  * version 2.1 of the License, or (at your option) any later version.
9*8dd5e09dSSadaf Ebrahimi  *
10*8dd5e09dSSadaf Ebrahimi  * This library is distributed in the hope that it will be useful,
11*8dd5e09dSSadaf Ebrahimi  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12*8dd5e09dSSadaf Ebrahimi  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13*8dd5e09dSSadaf Ebrahimi  * Lesser General Public License for more details.
14*8dd5e09dSSadaf Ebrahimi  *
15*8dd5e09dSSadaf Ebrahimi  * You should have received a copy of the GNU Lesser General Public License
16*8dd5e09dSSadaf Ebrahimi  * along with this program; see the file COPYING.LIB. If not, write to the
17*8dd5e09dSSadaf Ebrahimi  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
18*8dd5e09dSSadaf Ebrahimi  * Boston, MA 02110-1335, USA.
19*8dd5e09dSSadaf Ebrahimi  *
20*8dd5e09dSSadaf Ebrahimi  * Authors:
21*8dd5e09dSSadaf Ebrahimi  *      Steve Grubb <[email protected]>
22*8dd5e09dSSadaf Ebrahimi  */
23*8dd5e09dSSadaf Ebrahimi 
24*8dd5e09dSSadaf Ebrahimi #include "config.h"
25*8dd5e09dSSadaf Ebrahimi #include "../cap-ng.h"
26*8dd5e09dSSadaf Ebrahimi #include <stdlib.h>
27*8dd5e09dSSadaf Ebrahimi #include <stdio.h>
28*8dd5e09dSSadaf Ebrahimi #include <string.h>
29*8dd5e09dSSadaf Ebrahimi #include <errno.h>
30*8dd5e09dSSadaf Ebrahimi #include <fcntl.h>
31*8dd5e09dSSadaf Ebrahimi #include <sys/stat.h>
32*8dd5e09dSSadaf Ebrahimi 
get_last_cap(void)33*8dd5e09dSSadaf Ebrahimi static unsigned int get_last_cap(void)
34*8dd5e09dSSadaf Ebrahimi {
35*8dd5e09dSSadaf Ebrahimi 	int fd;
36*8dd5e09dSSadaf Ebrahimi 
37*8dd5e09dSSadaf Ebrahimi 	fd = open("/proc/sys/kernel/cap_last_cap", O_RDONLY);
38*8dd5e09dSSadaf Ebrahimi 	if (fd == -1) {
39*8dd5e09dSSadaf Ebrahimi 		return CAP_LAST_CAP;
40*8dd5e09dSSadaf Ebrahimi 	} else {
41*8dd5e09dSSadaf Ebrahimi 		char buf[8];
42*8dd5e09dSSadaf Ebrahimi 		int num = read(fd, buf, sizeof(buf));
43*8dd5e09dSSadaf Ebrahimi 		if (num > 0) {
44*8dd5e09dSSadaf Ebrahimi 			errno = 0;
45*8dd5e09dSSadaf Ebrahimi 			unsigned int val = strtoul(buf, NULL, 10);
46*8dd5e09dSSadaf Ebrahimi 			if (errno == 0)
47*8dd5e09dSSadaf Ebrahimi 				return val;
48*8dd5e09dSSadaf Ebrahimi 		}
49*8dd5e09dSSadaf Ebrahimi 		close(fd);
50*8dd5e09dSSadaf Ebrahimi 	}
51*8dd5e09dSSadaf Ebrahimi 	return CAP_LAST_CAP;
52*8dd5e09dSSadaf Ebrahimi }
53*8dd5e09dSSadaf Ebrahimi 
main(void)54*8dd5e09dSSadaf Ebrahimi int main(void)
55*8dd5e09dSSadaf Ebrahimi {
56*8dd5e09dSSadaf Ebrahimi 	int rc;
57*8dd5e09dSSadaf Ebrahimi 	unsigned int i, len, last = get_last_cap();
58*8dd5e09dSSadaf Ebrahimi 	char *text;
59*8dd5e09dSSadaf Ebrahimi 	void *saved;
60*8dd5e09dSSadaf Ebrahimi 
61*8dd5e09dSSadaf Ebrahimi 	puts("Doing basic bit tests...");
62*8dd5e09dSSadaf Ebrahimi 	capng_clear(CAPNG_SELECT_BOTH);
63*8dd5e09dSSadaf Ebrahimi 	if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_NONE) {
64*8dd5e09dSSadaf Ebrahimi 		puts("Failed clearing capabilities");
65*8dd5e09dSSadaf Ebrahimi 		abort();
66*8dd5e09dSSadaf Ebrahimi 	}
67*8dd5e09dSSadaf Ebrahimi 	saved = capng_save_state();
68*8dd5e09dSSadaf Ebrahimi 	capng_fill(CAPNG_SELECT_BOTH);
69*8dd5e09dSSadaf Ebrahimi 	if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_FULL) {
70*8dd5e09dSSadaf Ebrahimi 		puts("Failed filling capabilities");
71*8dd5e09dSSadaf Ebrahimi 		abort();
72*8dd5e09dSSadaf Ebrahimi 	}
73*8dd5e09dSSadaf Ebrahimi 	// Need to detect if version 1 or 2 capabilities
74*8dd5e09dSSadaf Ebrahimi 	text = capng_print_caps_numeric(CAPNG_PRINT_BUFFER, CAPNG_SELECT_CAPS);
75*8dd5e09dSSadaf Ebrahimi 	len = strlen(text);
76*8dd5e09dSSadaf Ebrahimi 	free(text);
77*8dd5e09dSSadaf Ebrahimi 	if (len < 80 && last > 30)	// The kernel & headers are mismatched
78*8dd5e09dSSadaf Ebrahimi 		last = 30;
79*8dd5e09dSSadaf Ebrahimi 	// Now test that restore still works
80*8dd5e09dSSadaf Ebrahimi 	capng_restore_state(&saved);
81*8dd5e09dSSadaf Ebrahimi 	if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_NONE) {
82*8dd5e09dSSadaf Ebrahimi 		puts("Failed restoring capabilities");
83*8dd5e09dSSadaf Ebrahimi 		abort();
84*8dd5e09dSSadaf Ebrahimi 	}
85*8dd5e09dSSadaf Ebrahimi 	printf("Doing advanced bit tests for %d capabilities...\n", last);
86*8dd5e09dSSadaf Ebrahimi 	for (i=0; i<=last; i++) {
87*8dd5e09dSSadaf Ebrahimi 		const char *name;
88*8dd5e09dSSadaf Ebrahimi 		capng_clear(CAPNG_SELECT_BOTH);
89*8dd5e09dSSadaf Ebrahimi 		rc = capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, i);
90*8dd5e09dSSadaf Ebrahimi 		if (rc) {
91*8dd5e09dSSadaf Ebrahimi 			puts("Failed update test 1");
92*8dd5e09dSSadaf Ebrahimi 			abort();
93*8dd5e09dSSadaf Ebrahimi 		}
94*8dd5e09dSSadaf Ebrahimi 		rc = capng_have_capability(CAPNG_EFFECTIVE, i);
95*8dd5e09dSSadaf Ebrahimi 		if (rc == 0) {
96*8dd5e09dSSadaf Ebrahimi 			puts("Failed have capability test 1");
97*8dd5e09dSSadaf Ebrahimi 			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
98*8dd5e09dSSadaf Ebrahimi 					CAPNG_SELECT_CAPS);
99*8dd5e09dSSadaf Ebrahimi 			abort();
100*8dd5e09dSSadaf Ebrahimi 		}
101*8dd5e09dSSadaf Ebrahimi 		if(capng_have_capabilities(CAPNG_SELECT_CAPS)!=CAPNG_PARTIAL){
102*8dd5e09dSSadaf Ebrahimi 			puts("Failed have capabilities test 1");
103*8dd5e09dSSadaf Ebrahimi 			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
104*8dd5e09dSSadaf Ebrahimi 					CAPNG_SELECT_CAPS);
105*8dd5e09dSSadaf Ebrahimi 			abort();
106*8dd5e09dSSadaf Ebrahimi 		}
107*8dd5e09dSSadaf Ebrahimi #if CAP_LAST_CAP > 31
108*8dd5e09dSSadaf Ebrahimi 		rc = capng_update(CAPNG_ADD, CAPNG_BOUNDING_SET, i);
109*8dd5e09dSSadaf Ebrahimi 		if (rc) {
110*8dd5e09dSSadaf Ebrahimi 			puts("Failed bset update test 2");
111*8dd5e09dSSadaf Ebrahimi 			abort();
112*8dd5e09dSSadaf Ebrahimi 		}
113*8dd5e09dSSadaf Ebrahimi 		rc = capng_have_capability(CAPNG_BOUNDING_SET, i);
114*8dd5e09dSSadaf Ebrahimi 		if (rc == 0) {
115*8dd5e09dSSadaf Ebrahimi 			puts("Failed bset have capability test 2");
116*8dd5e09dSSadaf Ebrahimi 			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
117*8dd5e09dSSadaf Ebrahimi 					CAPNG_SELECT_BOTH);
118*8dd5e09dSSadaf Ebrahimi 			abort();
119*8dd5e09dSSadaf Ebrahimi 		}
120*8dd5e09dSSadaf Ebrahimi 		if(capng_have_capabilities(CAPNG_SELECT_BOUNDS)!=CAPNG_PARTIAL){
121*8dd5e09dSSadaf Ebrahimi 			puts("Failed bset have capabilities test 2");
122*8dd5e09dSSadaf Ebrahimi 			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
123*8dd5e09dSSadaf Ebrahimi 					CAPNG_SELECT_BOTH);
124*8dd5e09dSSadaf Ebrahimi 			abort();
125*8dd5e09dSSadaf Ebrahimi 		}
126*8dd5e09dSSadaf Ebrahimi #endif
127*8dd5e09dSSadaf Ebrahimi 		text=capng_print_caps_text(CAPNG_PRINT_BUFFER, CAPNG_EFFECTIVE);
128*8dd5e09dSSadaf Ebrahimi 		if (text == NULL) {
129*8dd5e09dSSadaf Ebrahimi 			puts("Failed getting print text to buffer");
130*8dd5e09dSSadaf Ebrahimi 			abort();
131*8dd5e09dSSadaf Ebrahimi 		}
132*8dd5e09dSSadaf Ebrahimi 		name = capng_capability_to_name(i);
133*8dd5e09dSSadaf Ebrahimi 		if (name == NULL) {
134*8dd5e09dSSadaf Ebrahimi 			printf("Failed converting capability %d to name\n", i);
135*8dd5e09dSSadaf Ebrahimi 			abort();
136*8dd5e09dSSadaf Ebrahimi 		}
137*8dd5e09dSSadaf Ebrahimi 		if (strcmp(text, name)) {
138*8dd5e09dSSadaf Ebrahimi 			puts("Failed print text comparison");
139*8dd5e09dSSadaf Ebrahimi 			printf("%s != %s\n", text, name);
140*8dd5e09dSSadaf Ebrahimi 			abort();
141*8dd5e09dSSadaf Ebrahimi 		}
142*8dd5e09dSSadaf Ebrahimi 		free(text);
143*8dd5e09dSSadaf Ebrahimi 		// Now make sure the mask part is working
144*8dd5e09dSSadaf Ebrahimi 		capng_fill(CAPNG_SELECT_BOTH);
145*8dd5e09dSSadaf Ebrahimi 		rc = capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, i);
146*8dd5e09dSSadaf Ebrahimi 		if (rc) {
147*8dd5e09dSSadaf Ebrahimi 			puts("Failed update test 3");
148*8dd5e09dSSadaf Ebrahimi 			abort();
149*8dd5e09dSSadaf Ebrahimi 		}
150*8dd5e09dSSadaf Ebrahimi 		// Should be partial
151*8dd5e09dSSadaf Ebrahimi 		if(capng_have_capabilities(CAPNG_SELECT_CAPS)!=CAPNG_PARTIAL){
152*8dd5e09dSSadaf Ebrahimi 			puts("Failed have capabilities test 3");
153*8dd5e09dSSadaf Ebrahimi 			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
154*8dd5e09dSSadaf Ebrahimi 					CAPNG_SELECT_CAPS);
155*8dd5e09dSSadaf Ebrahimi 			abort();
156*8dd5e09dSSadaf Ebrahimi 		}
157*8dd5e09dSSadaf Ebrahimi 		// Add back the bit and should be full capabilities
158*8dd5e09dSSadaf Ebrahimi 		rc = capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, i);
159*8dd5e09dSSadaf Ebrahimi 		if (rc) {
160*8dd5e09dSSadaf Ebrahimi 			puts("Failed update test 4");
161*8dd5e09dSSadaf Ebrahimi 			abort();
162*8dd5e09dSSadaf Ebrahimi 		}
163*8dd5e09dSSadaf Ebrahimi 		if (capng_have_capabilities(CAPNG_SELECT_CAPS) != CAPNG_FULL){
164*8dd5e09dSSadaf Ebrahimi 			puts("Failed have capabilities test 4");
165*8dd5e09dSSadaf Ebrahimi 			capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
166*8dd5e09dSSadaf Ebrahimi 					CAPNG_SELECT_CAPS);
167*8dd5e09dSSadaf Ebrahimi 			abort();
168*8dd5e09dSSadaf Ebrahimi 		}
169*8dd5e09dSSadaf Ebrahimi 	}
170*8dd5e09dSSadaf Ebrahimi 	// Now test the updatev function
171*8dd5e09dSSadaf Ebrahimi 	capng_clear(CAPNG_SELECT_BOTH);
172*8dd5e09dSSadaf Ebrahimi 	rc = capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE,
173*8dd5e09dSSadaf Ebrahimi 			CAP_CHOWN, CAP_FOWNER, CAP_KILL, -1);
174*8dd5e09dSSadaf Ebrahimi 	if (rc) {
175*8dd5e09dSSadaf Ebrahimi 		puts("Failed updatev test");
176*8dd5e09dSSadaf Ebrahimi 		abort();
177*8dd5e09dSSadaf Ebrahimi 	}
178*8dd5e09dSSadaf Ebrahimi 	rc = capng_have_capability(CAPNG_EFFECTIVE, CAP_CHOWN) &&
179*8dd5e09dSSadaf Ebrahimi 		capng_have_capability(CAPNG_EFFECTIVE, CAP_FOWNER) &&
180*8dd5e09dSSadaf Ebrahimi 		capng_have_capability(CAPNG_EFFECTIVE, CAP_KILL);
181*8dd5e09dSSadaf Ebrahimi 	if (rc == 0) {
182*8dd5e09dSSadaf Ebrahimi 		puts("Failed have updatev capability test");
183*8dd5e09dSSadaf Ebrahimi 		capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
184*8dd5e09dSSadaf Ebrahimi 				CAPNG_SELECT_CAPS);
185*8dd5e09dSSadaf Ebrahimi 		abort();
186*8dd5e09dSSadaf Ebrahimi 	}
187*8dd5e09dSSadaf Ebrahimi 
188*8dd5e09dSSadaf Ebrahimi 	return EXIT_SUCCESS;
189*8dd5e09dSSadaf Ebrahimi }
190*8dd5e09dSSadaf Ebrahimi 
191