delete_module02.c revision 72521cf0741034f67dd17107453cda9a9819264c
1/* 2 * Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * You should have received a copy of the GNU General Public License along 13 * with this program; if not, write the Free Software Foundation, Inc., 59 14 * Temple Place - Suite 330, Boston MA 02111-1307, USA. 15 * 16 */ 17/********************************************************** 18 * 19 * TEST IDENTIFIER : delete_module02 20 * 21 * EXECUTED BY : root / superuser 22 * 23 * TEST TITLE : Checking error conditions for delete_module(2) 24 * 25 * TEST CASE TOTAL : 5 26 * 27 * AUTHOR : Madhu T L <madhu.tarikere@wipro.com> 28 * 29 * SIGNALS 30 * Uses SIGUSR1 to pause before test if option set. 31 * (See the parse_opts(3) man page). 32 * 33 * DESCRIPTION 34 * Verify that, 35 * 1. delete_module(2) returns -1 and sets errno to ENOENT for nonexistent 36 * module entry. 37 * 2. delete_module(2) returns -1 and sets errno to EINVAL, if module 38 * name parameter is null terminated (zero length) string. 39 * 3. delete_module(2) returns -1 and sets errno to EFAULT, if 40 * module name parameter is outside program's accessible address space. 41 * 4. delete_module(2) returns -1 and sets errno to ENAMETOOLONG, if 42 * module name parameter is too long. 43 * 5. delete_module(2) returns -1 and sets errno to EPERM, if effective 44 * user id of the caller is not superuser. 45 * 46 * Setup: 47 * Setup signal handling. 48 * Test caller is super user 49 * Check existances of "nobody" user id. 50 * Initialize long module name 51 * Set expected errnos for logging 52 * Pause for SIGUSR1 if option specified. 53 * Initialize modname for each child process 54 * 55 * Test: 56 * Loop if the proper options are given. 57 * Perform testcase specific setup (if needed) 58 * Execute system call 59 * Check return code and error number, if matching, 60 * Issue PASS message 61 * Otherwise, 62 * Issue FAIL message 63 * Perform testcase specific cleanup (if needed) 64 * 65 * Cleanup: 66 * Print errno log and/or timing stats if options given 67 * 68 * USAGE: <for command-line> 69 * delete_module02 [-c n] [-e] [-f] [-h] [-i n] [-I x] [-p] [-P x] [-t] 70 * where, -c n : Run n copies concurrently. 71 * -e : Turn on errno logging. 72 * -f : Turn off functional testing 73 * -h : Show help screen 74 * -i n : Execute test n times. 75 * -I x : Execute test for x seconds. 76 * -p : Pause for SIGUSR1 before 77 * starting test. 78 * -P x : Pause for x seconds between 79 * iterations. 80 * -t : Turn on syscall timing. 81 * 82 ****************************************************************/ 83 84#include <errno.h> 85#include <pwd.h> 86#include <sys/types.h> 87#include <unistd.h> 88#include <limits.h> 89#if HAVE_LINUX_MODULE_H 90#include <linux/module.h> 91#else 92/* As per http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/include/linux/moduleparam.h?a=ppc#L17 ... */ 93#define MODULE_NAME_LEN ( 64 - sizeof(unsigned long) ) 94#endif 95#include <sys/mman.h> 96#include "test.h" 97#include "usctest.h" 98 99 100#define NULLMODNAME "" 101#define BASEMODNAME "dummy" 102#define LONGMODNAMECHAR 'm' /* Arbitrarily selected */ 103#define EXP_RET_VAL -1 104 105/* Test case structure */ 106struct test_case_t { 107 char *modname; 108 /* Expected errno. */ 109 int experrno; 110 char *desc; 111 /* Individual setup routine. */ 112 int (*setup)(void); 113 /* Individual cleanup routine */ 114 void (*cleanup)(void); 115}; 116 117char *TCID = "delete_module02"; 118static int exp_enos[] = { EPERM, EINVAL, ENOENT, EFAULT, ENAMETOOLONG, 0 }; 119static char nobody_uid[] = "nobody"; 120struct passwd *ltpuser; 121static char longmodname[MODULE_NAME_LEN]; 122static int testno; 123/* Name of the module */ 124static char modname[20]; 125 126char * bad_addr = 0; 127 128static void setup(void); 129static void cleanup(void); 130static int setup1(void); 131static void cleanup1(void); 132 133struct test_case_t; 134 135static struct test_case_t tdat[] = { 136 { modname, ENOENT, 137 "nonexistent module", NULL, NULL}, 138 { NULLMODNAME, ENOENT, 139 "null terminated module name", NULL, NULL}, 140 { (char *) -1, EFAULT, 141 "module name outside program's " 142 "accessible address space", NULL, NULL}, 143 { longmodname, ENOENT, 144 "long module name", NULL, NULL}, 145 { modname, EPERM, 146 "non-superuser", setup1, cleanup1}, 147}; 148 149int TST_TOTAL = sizeof(tdat) / sizeof(tdat[0]); 150 151int 152main(int argc, char **argv) 153{ 154 int lc; /* loop counter */ 155 char *msg; /* message returned from parse_opts */ 156 157 /* parse standard options */ 158 if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL) 159 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); 160 161 setup(); 162 163 for (lc = 0; TEST_LOOPING(lc); lc++) { 164 /* reset Tst_count in case we are looping */ 165 Tst_count = 0; 166 167 for (testno = 0; testno < TST_TOTAL; ++testno) { 168 if ((tdat[testno].setup) && (tdat[testno].setup())) { 169 /* setup() failed, skip this test */ 170 continue; 171 } 172 /* Test the system call */ 173 TEST(delete_module(tdat[testno].modname)); 174 TEST_ERROR_LOG(TEST_ERRNO); 175 printf("TEST_RETURN is %d, TEST_ERRNO is %d\n", 176 TEST_RETURN, TEST_ERRNO); 177 if ((TEST_RETURN == EXP_RET_VAL) && 178 (TEST_ERRNO == tdat[testno].experrno) ) { 179 tst_resm(TPASS, "Expected results for %s, " 180 "errno: %d", tdat[testno].desc, 181 TEST_ERRNO); 182 } else { 183 tst_resm(TFAIL, "Unexpected results for %s ; " 184 "returned %d (expected %d), " 185 "errno %d (expected %d)", 186 tdat[testno].desc, 187 TEST_RETURN, EXP_RET_VAL, 188 TEST_ERRNO, 189 tdat[testno].experrno); 190 } 191 if (tdat[testno].cleanup) { 192 tdat[testno].cleanup(); 193 } 194 } 195 } 196 cleanup(); 197 tst_exit(); 198} 199 200int 201setup1(void) 202{ 203 /* Change effective user id to nodody */ 204 if (seteuid(ltpuser->pw_uid) == -1) { 205 tst_resm(TBROK, "seteuid failed to set the effective" 206 " uid to %d", ltpuser->pw_uid); 207 return 1; 208 } 209 return 0; 210} 211 212void 213cleanup1(void) 214{ 215 /* Change effective user id to root */ 216 if (seteuid(0) == -1) { 217 tst_brkm(TBROK, NULL, "seteuid failed to set the effective" 218 " uid to root"); 219 } 220} 221 222/* 223 * setup() 224 * performs all ONE TIME setup for this test 225 */ 226void 227setup(void) 228{ 229 230 tst_sig(NOFORK, DEF_HANDLER, cleanup); 231 232 /* Check whether it is root */ 233 if (geteuid() != 0) { 234 tst_brkm(TBROK, NULL, "Must be root for this test!"); 235 236 } 237 238 /*if (tst_kvercmp(2,5,48) >= 0) 239 tst_brkm(TCONF, NULL, "This test will not work on " 240 "kernels after 2.5.48"); 241 */ 242 243 /* Check for nobody_uid user id */ 244 if ((ltpuser = getpwnam(nobody_uid)) == NULL) { 245 tst_brkm(TBROK, NULL, "Required user %s doesn't exists", 246 nobody_uid); 247 } 248 249 /* Initialize longmodname to LONGMODNAMECHAR character */ 250 memset(longmodname, LONGMODNAMECHAR, MODULE_NAME_LEN - 1); 251 252 /* set the expected errnos... */ 253 TEST_EXP_ENOS(exp_enos); 254 255 /* Pause if that option was specified 256 * TEST_PAUSE contains the code to fork the test with the -c option. 257 */ 258 TEST_PAUSE; 259 260 /* Get unique module name for each child process */ 261 if (sprintf(modname, "%s_%d", BASEMODNAME, getpid()) <= 0) { 262 tst_brkm(TBROK, NULL, "Failed to initialize module name"); 263 } 264 bad_addr = mmap(0, 1, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 265 if (bad_addr == MAP_FAILED) { 266 tst_brkm(TBROK, cleanup, "mmap failed"); 267 } 268 tdat[2].modname = bad_addr; 269 270} 271 272/* 273 * cleanup() 274 * performs all ONE TIME cleanup for this test at 275 * completion or premature exit 276 */ 277void 278cleanup(void) 279{ 280 /* 281 * print timing stats if that option was specified. 282 * print errno log if that option was specified. 283 */ 284 TEST_CLEANUP; 285}