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