hugeshmget05.c revision 0b9589f3f9c0345b29cfcf7da5a1253c708303eb
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 "ipcshm.h" 64#include "safe_macros.h" 65#include "mem.h" 66 67char *TCID = "hugeshmget05"; 68int TST_TOTAL = 1; 69 70static size_t shm_size; 71static int shm_id_1 = -1; 72static uid_t ltp_uid; 73static char *ltp_user = "nobody"; 74 75static long hugepages = 128; 76static option_t options[] = { 77 {"s:", &sflag, &nr_opt}, 78 {NULL, NULL, NULL} 79}; 80 81static void do_child(void); 82 83int main(int ac, char **av) 84{ 85 const char *msg; 86 pid_t pid; 87 int status; 88 89 msg = parse_opts(ac, av, options, &help); 90 if (msg != NULL) 91 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); 92 if (sflag) 93 hugepages = SAFE_STRTOL(NULL, nr_opt, 0, LONG_MAX); 94 95 setup(); 96 97 switch (pid = fork()) { 98 case -1: 99 tst_brkm(TBROK | TERRNO, cleanup, "fork"); 100 case 0: 101 /* set the user ID of the child to the non root user */ 102 if (setuid(ltp_uid) == -1) 103 tst_brkm(TBROK | TERRNO, cleanup, "setuid"); 104 do_child(); 105 tst_exit(); 106 default: 107 /* wait for the child to return */ 108 if (waitpid(pid, &status, 0) == -1) 109 tst_brkm(TBROK | TERRNO, cleanup, "waitpid"); 110 } 111 cleanup(); 112 tst_exit(); 113} 114 115static void do_child(void) 116{ 117 int lc; 118 119 for (lc = 0; TEST_LOOPING(lc); lc++) { 120 tst_count = 0; 121 122 TEST(shmget(shmkey, shm_size, SHM_HUGETLB | SHM_RW)); 123 if (TEST_RETURN != -1) { 124 tst_resm(TFAIL, "shmget succeeded unexpectedly"); 125 continue; 126 } 127 if (TEST_ERRNO == EACCES) 128 tst_resm(TPASS | TTERRNO, "shmget failed as expected"); 129 else 130 tst_resm(TFAIL | TTERRNO, "shmget failed unexpectedly " 131 "- expect errno=EACCES, got"); 132 } 133} 134 135void setup(void) 136{ 137 long hpage_size; 138 139 tst_require_root(NULL); 140 tst_sig(FORK, DEF_HANDLER, cleanup); 141 tst_tmpdir(); 142 143 orig_hugepages = get_sys_tune("nr_hugepages"); 144 set_sys_tune("nr_hugepages", hugepages, 1); 145 hpage_size = read_meminfo("Hugepagesize:") * 1024; 146 147 shm_size = hpage_size * hugepages / 2; 148 update_shm_size(&shm_size); 149 shmkey = getipckey(); 150 shm_id_1 = shmget(shmkey, shm_size, 151 SHM_HUGETLB | SHM_RW | IPC_CREAT | IPC_EXCL); 152 if (shm_id_1 == -1) 153 tst_brkm(TBROK | TERRNO, cleanup, "shmget #setup"); 154 155 /* get the userid for a non-root user */ 156 ltp_uid = getuserid(ltp_user); 157 158 TEST_PAUSE; 159} 160 161void cleanup(void) 162{ 163 TEST_CLEANUP; 164 165 rm_shm(shm_id_1); 166 167 set_sys_tune("nr_hugepages", orig_hugepages, 0); 168 169 tst_rmdir(); 170} 171