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