Home | History | Annotate | Download | only in cap_bound
      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