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