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 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 #define max(x,y) (x > y ? x : y) 89 #if HAVE_DECL_PR_CAPBSET_READ 90 ret = prctl(PR_CAPBSET_READ, max(INSANE, CAP_LAST_CAP + 1)); 91 #else 92 errno = ENOSYS; 93 ret = -1; 94 #endif 95 if (ret != -1) { 96 tst_resm(TFAIL, "prctl(PR_CAPBSET_READ, %d) returned %d\n", 97 CAP_LAST_CAP + 1, ret); 98 tst_resm(TINFO, " %d is CAP_LAST_CAP+1 and should not exist\n", 99 CAP_LAST_CAP + 1); 100 tst_exit(); 101 } 102 tst_resm(TPASS, "PR_CAPBSET_READ tests passed\n"); 103 #else 104 tst_resm(TCONF, "System doesn't have POSIX capabilities."); 105 #endif 106 tst_exit(); 107 } 108