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