1 /* 2 * 3 * Copyright (c) International Business Machines Corp., 2001 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 * shmget05.c 23 * 24 * DESCRIPTION 25 * shmget05 - 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 shmget() 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 * shmget05 [-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 * 55 * RESTRICTIONS 56 * test must be run at root 57 */ 58 59 #include "ipcshm.h" 60 #include <sys/types.h> 61 #include <sys/wait.h> 62 63 char *TCID = "shmget05"; 64 int TST_TOTAL = 1; 65 66 int shm_id_1 = -1; 67 68 uid_t ltp_uid; 69 char *ltp_user = "nobody"; 70 71 int main(int ac, char **av) 72 { 73 int pid; 74 void do_child(void); 75 76 tst_parse_opts(ac, av, NULL, NULL); 77 78 setup(); /* global setup */ 79 80 if ((pid = FORK_OR_VFORK()) == -1) { 81 tst_brkm(TBROK, cleanup, "could not fork"); 82 } 83 84 if (pid == 0) { /* child */ 85 /* set the user ID of the child to the non root user */ 86 if (setuid(ltp_uid) == -1) { 87 tst_resm(TBROK, "setuid() failed"); 88 exit(1); 89 } 90 91 do_child(); 92 93 cleanup(); 94 95 } else { /* parent */ 96 /* wait for the child to return */ 97 if (waitpid(pid, NULL, 0) == -1) { 98 tst_brkm(TBROK, cleanup, "waitpid failed"); 99 } 100 101 /* if it exists, remove the shared memory resource */ 102 rm_shm(shm_id_1); 103 104 tst_rmdir(); 105 } 106 tst_exit(); 107 } 108 109 /* 110 * do_child - make the TEST call as the child process 111 */ 112 void do_child(void) 113 { 114 int lc; 115 116 /* The following loop checks looping state if -i option given */ 117 118 for (lc = 0; TEST_LOOPING(lc); lc++) { 119 /* reset tst_count in case we are looping */ 120 tst_count = 0; 121 122 /* 123 * Look for a failure ... 124 */ 125 126 TEST(shmget(shmkey, SHM_SIZE, SHM_RW)); 127 128 if (TEST_RETURN != -1) { 129 tst_resm(TFAIL, "call succeeded when error expected"); 130 continue; 131 } 132 133 switch (TEST_ERRNO) { 134 case EACCES: 135 tst_resm(TPASS, "expected failure - errno = " 136 "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO)); 137 break; 138 default: 139 tst_resm(TFAIL, "call failed with an " 140 "unexpected error - %d : %s", 141 TEST_ERRNO, strerror(TEST_ERRNO)); 142 break; 143 } 144 } 145 } 146 147 /* 148 * setup() - performs all the ONE TIME setup for this test. 149 */ 150 void setup(void) 151 { 152 tst_require_root(); 153 154 tst_sig(FORK, DEF_HANDLER, cleanup); 155 156 TEST_PAUSE; 157 158 /* 159 * Create a temporary directory and cd into it. 160 * This helps to ensure that a unique msgkey is created. 161 * See ../lib/libipc.c for more information. 162 */ 163 tst_tmpdir(); 164 165 /* get an IPC resource key */ 166 shmkey = getipckey(); 167 168 /* create a shared memory segment with read and write permissions */ 169 if ((shm_id_1 = shmget(shmkey, SHM_SIZE, 170 SHM_RW | IPC_CREAT | IPC_EXCL)) == -1) { 171 tst_brkm(TBROK, cleanup, "Failed to create shared memory " 172 "segment in setup"); 173 } 174 175 /* get the userid for a non root user */ 176 ltp_uid = getuserid(ltp_user); 177 } 178 179 /* 180 * cleanup() - performs all the ONE TIME cleanup for this test at completion 181 * or premature exit. 182 */ 183 void cleanup(void) 184 { 185 186 } 187