1 /* 2 * 3 * Copyright (c) International Business Machines Corp., 2004 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 * NAME 22 * hugeshmat03.c 23 * 24 * DESCRIPTION 25 * hugeshmat03 - test for EACCES error 26 * 27 * ALGORITHM 28 * create a shared memory segment with root only read & write permissions 29 * fork a child process 30 * if child 31 * set the ID of the child process to that of "nobody" 32 * loop if that option was specified 33 * call shmat() using the TEST() macro 34 * check the errno value 35 * issue a PASS message if we get EACCES 36 * otherwise, the tests fails 37 * issue a FAIL message 38 * call cleanup 39 * if parent 40 * wait for child to exit 41 * remove the shared memory segment 42 * 43 * USAGE: <for command-line> 44 * hugeshmat03 [-c n] [-e] [-i n] [-I x] [-P x] [-t] 45 * where, -c n : Run n copies concurrently. 46 * -e : Turn on errno logging. 47 * -i n : Execute test n times. 48 * -I x : Execute test for x seconds. 49 * -P x : Pause for x seconds between iterations. 50 * -t : Turn on syscall timing. 51 * 52 * HISTORY 53 * 03/2001 - Written by Wayne Boyer 54 * 04/2004 - Updated by Robbie Williamson 55 * 56 * RESTRICTIONS 57 * test must be run at root 58 */ 59 60 #include "hugetlb.h" 61 #include "safe_macros.h" 62 #include "mem.h" 63 64 char *TCID = "hugeshmat03"; 65 int TST_TOTAL = 1; 66 67 static size_t shm_size; 68 static int shm_id_1 = -1; 69 static void *addr; 70 static uid_t ltp_uid; 71 static char *ltp_user = "nobody"; 72 73 static long hugepages = 128; 74 static option_t options[] = { 75 {"s:", &sflag, &nr_opt}, 76 {NULL, NULL, NULL} 77 }; 78 79 static void do_child(void); 80 81 int main(int ac, char **av) 82 { 83 int status; 84 pid_t pid; 85 86 tst_parse_opts(ac, av, options, NULL); 87 88 if (sflag) 89 hugepages = SAFE_STRTOL(NULL, nr_opt, 0, LONG_MAX); 90 91 setup(); 92 93 switch (pid = fork()) { 94 case -1: 95 tst_brkm(TBROK | TERRNO, cleanup, "fork"); 96 case 0: 97 if (setuid(ltp_uid) == -1) 98 tst_brkm(TBROK | TERRNO, cleanup, "setuid"); 99 do_child(); 100 tst_exit(); 101 default: 102 if (waitpid(pid, &status, 0) == -1) 103 tst_brkm(TBROK | TERRNO, cleanup, "waitpid"); 104 } 105 cleanup(); 106 tst_exit(); 107 } 108 109 static void do_child(void) 110 { 111 int lc; 112 113 for (lc = 0; TEST_LOOPING(lc); lc++) { 114 tst_count = 0; 115 116 addr = shmat(shm_id_1, NULL, 0); 117 if (addr != (void *)-1) { 118 tst_resm(TFAIL, "shmat succeeded unexpectedly"); 119 continue; 120 } 121 if (errno == EACCES) 122 tst_resm(TPASS | TERRNO, "shmat failed as expected"); 123 else 124 tst_resm(TFAIL | TERRNO, "shmat failed unexpectedly " 125 "- expect errno=EACCES, got"); 126 } 127 } 128 129 void setup(void) 130 { 131 long hpage_size; 132 133 tst_require_root(); 134 check_hugepage(); 135 tst_sig(FORK, DEF_HANDLER, cleanup); 136 tst_tmpdir(); 137 138 orig_hugepages = get_sys_tune("nr_hugepages"); 139 set_sys_tune("nr_hugepages", hugepages, 1); 140 hpage_size = read_meminfo("Hugepagesize:") * 1024; 141 142 shm_size = hpage_size * hugepages / 2; 143 update_shm_size(&shm_size); 144 shmkey = getipckey(cleanup); 145 shm_id_1 = shmget(shmkey, shm_size, 146 SHM_HUGETLB | SHM_RW | IPC_CREAT | IPC_EXCL); 147 if (shm_id_1 == -1) 148 tst_brkm(TBROK | TERRNO, cleanup, "shmget"); 149 150 ltp_uid = getuserid(cleanup, ltp_user); 151 152 TEST_PAUSE; 153 } 154 155 void cleanup(void) 156 { 157 rm_shm(shm_id_1); 158 159 set_sys_tune("nr_hugepages", orig_hugepages, 0); 160 161 tst_rmdir(); 162 } 163