create_module02.c revision 4edbd06d0a42d7d889fb85364bba42bae8595413
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 : create_module02 20 * 21 * EXECUTED BY : root / superuser 22 * 23 * TEST TITLE : Checking error conditions for create_module(2) 24 * 25 * TEST CASE TOTAL : 8 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. create_module(2) returns -1 and sets errno to EPERM, if effective 36 * user id of the caller is not superuser. 37 * 2. create_module(2) returns -1 and sets errno to EFAULT, if module 38 * name is outside the program's accessible address space. 39 * 3. create_module(2) returns -1 and sets errno to EFAULT, if module 40 * name parameter is NULL. 41 * 4. create_module(2) returns -1 and sets errno to EINVAL, if module 42 * name parameter is null terminated (zero length) string. 43 * 5. create_module(2) returns -1 and sets errno to EEXIST, if module 44 * entry with the same name already exists. 45 * 6. create_module(2) returns -1 and sets errno to EINVAL, if module 46 * size parameter is too small. 47 * 7. create_module(2) returns -1 and sets errno to ENAMETOOLONG, if 48 * module name parameter is too long. 49 * 8. create_module(2) returns -1 and sets errno to ENOMEM, if module 50 * size parameter is too large. 51 * 52 * Setup: 53 * Setup signal handling. 54 * Test caller is super user 55 * Check existances of "nobody" user id. 56 * Initialize long module name 57 * Set expected errnos for logging 58 * Pause for SIGUSR1 if option specified. 59 * Initialize modname for each child process 60 * 61 * Test: 62 * Loop if the proper options are given. 63 * Execute system call 64 * Check return code and error number, if matching, 65 * Issue PASS message 66 * Otherwise, 67 * Issue FAIL message 68 * 69 * Cleanup: 70 * Print errno log and/or timing stats if options given 71 * 72 * USAGE: <for command-line> 73 * create_module02 [-c n] [-e] [-f] [-h] [-i n] [-I x] [-p] [-P x] [-t] 74 * where, -c n : Run n copies concurrently. 75 * -e : Turn on errno logging. 76 * -f : Turn off functional testing 77 * -h : Show help screen 78 * -i n : Execute test n times. 79 * -I x : Execute test for x seconds. 80 * -p : Pause for SIGUSR1 before starting 81 * -P x : Pause for x seconds between iterations. 82 * -t : Turn on syscall timing. 83 * 84 ****************************************************************/ 85 86#include <errno.h> 87#include <pwd.h> 88#include <sys/types.h> 89#include <asm/page.h> 90#include <asm/atomic.h> 91#include <linux/module.h> 92#include "test.h" 93#include "usctest.h" 94 95extern int Tst_count; 96 97#define MODSIZE 10000 /* Arbitrarily selected MODSIZE */ 98#define NULLMODNAME "" 99#define MAXMODSIZE 0xffffffffffffffff /* Max size of size_t */ 100#define SMALLMODSIZE 1 /* Arbitrarily selected SMALLMODSIZE */ 101#define BASEMODNAME "dummy" 102#define LONGMODNAMECHAR 'm' /* Arbitrarily selected the alphabet */ 103#define MODNAMEMAX (PAGE_SIZE + 1) 104 105struct test_case_t { /* test case structure */ 106 char *modname; 107 size_t size; 108 caddr_t retval; /* syscall return value */ 109 int experrno; /* expected errno */ 110 char *desc; 111 int (*setup)(void); /* Individual setup routine */ 112 void (*cleanup)(void); /* Individual cleanup routine */ 113}; 114 115char *TCID = "create_module02"; 116static int exp_enos[]={EFAULT, EPERM, EEXIST, EINVAL, ENOMEM, ENAMETOOLONG, 0}; 117static char nobody_uid[] = "nobody"; 118struct passwd *ltpuser; 119static char longmodname[MODNAMEMAX]; 120static int testno; 121static char modname[20]; /* Name of the module */ 122 123static void setup(void); 124static void cleanup(void); 125static int setup1(void); 126static void cleanup1(void); 127static int setup2(void); 128static void cleanup2(void); 129 130static struct test_case_t tdat[] = { 131 { modname, MODSIZE, (caddr_t)-1, EPERM, 132 "non-superuser", setup1, cleanup1}, 133 { (char *)-1, MODSIZE, (caddr_t)-1, EFAULT, 134 "module name outside the program's accessible address space", NULL, NULL}, 135 { NULL, MODSIZE, (caddr_t)-1, EFAULT, 136 "NULL module name", NULL, NULL}, 137 { NULLMODNAME, MODSIZE, (caddr_t)-1, EINVAL, 138 "null terminated module name", NULL, NULL}, 139 { modname, MODSIZE, (caddr_t)-1, EEXIST, 140 "already existing module", setup2, cleanup2}, 141 { modname, SMALLMODSIZE, (caddr_t)-1, EINVAL, 142 "insufficient module size", NULL, NULL}, 143 { longmodname, MODSIZE, (caddr_t)-1, ENAMETOOLONG, 144 "long module name", NULL, NULL}, 145 146 /* 147 *This test case is giving segmentation fault on 148 * 2.4.* series, but works as expected with 2.5.* series of kernel. 149 */ 150 { modname, MAXMODSIZE, (caddr_t)-1, ENOMEM, 151 "large module size", NULL, NULL}, 152}; 153 154int TST_TOTAL = sizeof(tdat) / sizeof(tdat[0]); 155 156int 157main(int argc, char **argv) 158{ 159 int lc; /* loop counter */ 160 char *msg; /* message returned from parse_opts */ 161 162 /* parse standard options */ 163 if ((msg = parse_opts(argc, argv, (option_t *)NULL, NULL)) != 164 (char *)NULL) { 165 tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg); 166 } 167 168 setup(); 169 170 /* check looping state if -i option is given */ 171 for (lc = 0; TEST_LOOPING(lc); lc++) { 172 /* reset Tst_count in case we are looping */ 173 Tst_count = 0; 174 175 for (testno = 0; testno < TST_TOTAL; ++testno) { 176 if( (tdat[testno].setup) && (tdat[testno].setup()) ) { 177 /* setup() failed, skip this test */ 178 continue; 179 } 180 181 TEST(create_module(tdat[testno].modname, 182 tdat[testno].size)); 183 TEST_ERROR_LOG(TEST_ERRNO); 184 if ( (TEST_RETURN == (int) tdat[testno].retval) && 185 (TEST_ERRNO == tdat[testno].experrno) ) { 186 tst_resm(TPASS, "Expected results for %s, " 187 "errno: %d", 188 tdat[testno].desc, TEST_ERRNO); 189 } else { 190 tst_resm(TFAIL, "Unexpected results for %s ; " 191 "returned %d (expected %d), errno %d " 192 "(expected %d)", tdat[testno].desc, 193 TEST_RETURN, tdat[testno].retval, 194 TEST_ERRNO, tdat[testno].experrno); 195 } 196 if(tdat[testno].cleanup) { 197 tdat[testno].cleanup(); 198 } 199 } 200 } 201 cleanup(); 202 203 /*NOTREACHED*/ 204 return 0; 205} 206 207int 208setup1(void) 209{ 210 /* Change effective user id to nodody */ 211 if (seteuid(ltpuser->pw_uid) == -1) { 212 tst_resm(TBROK, "seteuid failed to set the effective" 213 " uid to %d", ltpuser->pw_uid); 214 return 1; 215 } 216 return 0; 217} 218 219void 220cleanup1(void) 221{ 222 /* Change effective user id to root */ 223 if (seteuid(0) == -1) { 224 tst_brkm(TBROK, tst_exit, "seteuid failed to set the effective" 225 " uid to root"); 226 } 227} 228 229int 230setup2(void) 231{ 232 /* Create a loadable module entry */ 233 if(create_module(modname, MODSIZE) == -1) { 234 tst_resm(TBROK, "Failed to create module entry" 235 " for %s", modname); 236 return 1; 237 } 238 return 0; 239} 240 241void 242cleanup2(void) 243{ 244 /* Remove loadable module entry */ 245 if(delete_module(modname) == -1) { 246 tst_brkm(TBROK, tst_exit, "Failed to delete module entry" 247 " for %s", modname); 248 } 249} 250 251/* 252 * setup() 253 * performs all ONE TIME setup for this test 254 */ 255void 256setup(void) 257{ 258 /* capture signals */ 259 tst_sig(NOFORK, DEF_HANDLER, cleanup); 260 261 /* Check whether it is root */ 262 if (geteuid() != 0) { 263 tst_brkm(TBROK, tst_exit, "Must be root for this test!"); 264 /*NOTREACHED*/ 265 } 266 267 if (tst_kvercmp(2,5,48) >= 0) 268 tst_brkm(TCONF, tst_exit, "This test will not work on " 269 "kernels after 2.5.48"); 270 271 /* Check for nobody_uid user id */ 272 if( (ltpuser = getpwnam(nobody_uid)) == NULL) { 273 tst_brkm(TBROK, tst_exit, "Required user %s doesn't exists", 274 nobody_uid); 275 /*NOTREACHED*/ 276 } 277 278 /* Initialize longmodname to LONGMODNAMECHAR character */ 279 memset(longmodname, LONGMODNAMECHAR, MODNAMEMAX - 1); 280 281 /* set the expected errnos... */ 282 TEST_EXP_ENOS(exp_enos); 283 284 /* Pause if that option was specified 285 * TEST_PAUSE contains the code to fork the test with the -c option. 286 */ 287 TEST_PAUSE; 288 289 /* Get unique module name for each child process */ 290 if( sprintf(modname, "%s_%d",BASEMODNAME, getpid()) == -1) { 291 tst_brkm(TBROK, tst_exit, "Failed to initialize module name"); 292 } 293} 294 295/* 296 * cleanup() 297 * performs all ONE TIME cleanup for this test at 298 * completion or premature exit 299 */ 300void 301cleanup(void) 302{ 303 /* 304 * print timing stats if that option was specified. 305 * print errno log if that option was specified. 306 */ 307 TEST_CLEANUP; 308 309 /* exit with return code appropriate for results */ 310 tst_exit(); 311 /*NOTREACHED*/ 312} 313