xref: /aosp_15_r20/external/ltp/testcases/kernel/security/cap_bound/cap_bounds_r.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 /******************************************************************************/
2 /*                                                                            */
3 /* Copyright (c) International Business Machines  Corp., 2007, 2008           */
4 /*                                                                            */
5 /* This program is free software;  you can redistribute it and/or modify      */
6 /* it under the terms of the GNU General Public License as published by       */
7 /* the Free Software Foundation; either version 2 of the License, or          */
8 /* (at your option) any later version.                                        */
9 /*                                                                            */
10 /* This program 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                  */
13 /* the GNU General Public License for more details.                           */
14 /*                                                                            */
15 /* You should have received a copy of the GNU General Public License          */
16 /* along with this program;  if not, write to the Free Software               */
17 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA    */
18 /*                                                                            */
19 /******************************************************************************/
20 /*
21  * File: cap_bounds_r.c
22  * Author: Serge Hallyn
23  * Purpose: test reading of capability bounding set.
24  * 	Test each valid cap value, as well as edge cases
25  */
26 
27 #include <errno.h>
28 #include "config.h"
29 #if HAVE_SYS_CAPABILITY_H
30 #include <linux/types.h>
31 #include <sys/capability.h>
32 #endif
33 #include <sys/prctl.h>
34 #include <unistd.h>
35 #include "test.h"
36 
37 #define PROC_CAP_LAST "/proc/sys/kernel/cap_last_cap"
38 
39 char *TCID = "cap_bounds_r";
40 int TST_TOTAL = 1;
41 
main(void)42 int main(void)
43 {
44 #ifdef HAVE_LIBCAP
45 	int ret = 1;
46 	int i;
47 	int cap_last_cap = CAP_LAST_CAP;
48 
49 	if (access(PROC_CAP_LAST, R_OK) == 0) {
50 		SAFE_FILE_SCANF(NULL, PROC_CAP_LAST, "%d", &cap_last_cap);
51 		if (cap_last_cap > CAP_LAST_CAP)
52 		       cap_last_cap = CAP_LAST_CAP;
53 	}
54 
55 	for (i = 0; i <= cap_last_cap; i++) {
56 #if HAVE_DECL_PR_CAPBSET_READ
57 		ret = prctl(PR_CAPBSET_READ, i);
58 #else
59 		errno = ENOSYS;
60 		ret = -1;
61 #endif
62 		if (ret != 1) {
63 			tst_resm(TFAIL,
64 				 "prctl(PR_CAPBSET_READ, %d) returned %d\n", i,
65 				 ret);
66 			if (ret == -1)
67 				tst_resm(TINFO, "errno was %d\n", errno);
68 			tst_exit();
69 		}
70 	}
71 #if HAVE_DECL_PR_CAPBSET_READ
72 	ret = prctl(PR_CAPBSET_READ, -1);
73 #else
74 	errno = ENOSYS;
75 	ret = -1;
76 #endif
77 	if (ret != -1) {
78 		tst_brkm(TFAIL, NULL,
79 			 "prctl(PR_CAPBSET_READ, -1) returned %d\n",
80 			 ret);
81 	}
82 
83 	/* Ideally I'd check CAP_LAST_CAP+1, but userspace
84 	 * tends to be far too unreliable to trust CAP_LAST_CAP>
85 	 * We could test using kernel API, but that's what we're
86 	 * testing...  So let's take an insanely high value */
87 #define INSANE 63
88 #if HAVE_DECL_PR_CAPBSET_READ
89 	ret = prctl(PR_CAPBSET_READ, MAX(INSANE, CAP_LAST_CAP + 1));
90 #else
91 	errno = ENOSYS;
92 	ret = -1;
93 #endif
94 	if (ret != -1) {
95 		tst_resm(TFAIL, "prctl(PR_CAPBSET_READ, %d) returned %d\n",
96 			 CAP_LAST_CAP + 1, ret);
97 		tst_resm(TINFO, " %d is CAP_LAST_CAP+1 and should not exist\n",
98 			 CAP_LAST_CAP + 1);
99 		tst_exit();
100 	}
101 	tst_resm(TPASS, "PR_CAPBSET_READ tests passed\n");
102 #else
103 	tst_resm(TCONF, "System doesn't have POSIX capabilities.");
104 #endif
105 	tst_exit();
106 }
107