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., 14 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 (at) 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 <unistd.h> 90 #include <limits.h> 91 #include <asm/atomic.h> 92 #include <linux/module.h> 93 #include "test.h" 94 95 #ifndef PAGE_SIZE 96 #define PAGE_SIZE sysconf(_SC_PAGE_SIZE) 97 #endif 98 99 #define MODSIZE 10000 /* Arbitrarily selected MODSIZE */ 100 #define NULLMODNAME "" 101 #define MAXMODSIZE 0xffffffffffffffff /* Max size of size_t */ 102 #define SMALLMODSIZE 1 /* Arbitrarily selected SMALLMODSIZE */ 103 #define BASEMODNAME "dummy" 104 #define LONGMODNAMECHAR 'm' /* Arbitrarily selected the alphabet */ 105 #define MODNAMEMAX (PAGE_SIZE + 1) 106 107 struct test_case_t { /* test case structure */ 108 char *modname; 109 size_t size; 110 caddr_t retval; /* syscall return value */ 111 int experrno; /* expected errno */ 112 char *desc; 113 int (*setup) (void); /* Individual setup routine */ 114 void (*cleanup) (void); /* Individual cleanup routine */ 115 }; 116 117 char *TCID = "create_module02"; 118 static char nobody_uid[] = "nobody"; 119 struct passwd *ltpuser; 120 static char longmodname[MODNAMEMAX]; 121 static int testno; 122 static char modname[20]; /* Name of the module */ 123 124 static void setup(void); 125 static void cleanup(void); 126 static int setup1(void); 127 static void cleanup1(void); 128 static int setup2(void); 129 static void cleanup2(void); 130 131 static struct test_case_t tdat[] = { 132 {modname, MODSIZE, (caddr_t) - 1, EPERM, 133 "non-superuser", setup1, cleanup1}, 134 {(char *)-1, MODSIZE, (caddr_t) - 1, EFAULT, 135 "module name outside the program's accessible address space", NULL, 136 NULL}, 137 {NULL, MODSIZE, (caddr_t) - 1, EFAULT, 138 "NULL module name", NULL, NULL}, 139 {NULLMODNAME, MODSIZE, (caddr_t) - 1, EINVAL, 140 "null terminated module name", NULL, NULL}, 141 {modname, MODSIZE, (caddr_t) - 1, EEXIST, 142 "already existing module", setup2, cleanup2}, 143 {modname, SMALLMODSIZE, (caddr_t) - 1, EINVAL, 144 "insufficient module size", NULL, NULL}, 145 {longmodname, MODSIZE, (caddr_t) - 1, ENAMETOOLONG, 146 "long module name", NULL, NULL}, 147 148 /* 149 *This test case is giving segmentation fault on 150 * 2.4.* series, but works as expected with 2.5.* series of kernel. 151 */ 152 {modname, MAXMODSIZE, (caddr_t) - 1, ENOMEM, 153 "large module size", NULL, NULL}, 154 }; 155 156 int TST_TOTAL = sizeof(tdat) / sizeof(tdat[0]); 157 158 int main(int argc, char **argv) 159 { 160 int lc; 161 162 tst_parse_opts(argc, argv, NULL, NULL); 163 164 setup(); 165 166 for (lc = 0; TEST_LOOPING(lc); lc++) { 167 /* reset tst_count in case we are looping */ 168 tst_count = 0; 169 170 for (testno = 0; testno < TST_TOTAL; ++testno) { 171 if ((tdat[testno].setup) && (tdat[testno].setup())) { 172 /* setup() failed, skip this test */ 173 continue; 174 } 175 176 TEST(create_module(tdat[testno].modname, 177 tdat[testno].size)); 178 if ((TEST_RETURN == (int)tdat[testno].retval) && 179 (TEST_ERRNO == tdat[testno].experrno)) { 180 tst_resm(TPASS, "Expected results for %s, " 181 "errno: %d", 182 tdat[testno].desc, TEST_ERRNO); 183 } else { 184 tst_resm(TFAIL, "Unexpected results for %s ; " 185 "returned %d (expected %d), errno %d " 186 "(expected %d)", tdat[testno].desc, 187 TEST_RETURN, tdat[testno].retval, 188 TEST_ERRNO, tdat[testno].experrno); 189 } 190 if (tdat[testno].cleanup) { 191 tdat[testno].cleanup(); 192 } 193 } 194 } 195 cleanup(); 196 tst_exit(); 197 } 198 199 int setup1(void) 200 { 201 /* Change effective user id to nodody */ 202 if (seteuid(ltpuser->pw_uid) == -1) { 203 tst_resm(TBROK, "seteuid failed to set the effective" 204 " uid to %d", ltpuser->pw_uid); 205 return 1; 206 } 207 return 0; 208 } 209 210 void cleanup1(void) 211 { 212 /* Change effective user id to root */ 213 if (seteuid(0) == -1) { 214 tst_brkm(TBROK, NULL, "seteuid failed to set the effective" 215 " uid to root"); 216 } 217 } 218 219 int setup2(void) 220 { 221 /* Create a loadable module entry */ 222 if (create_module(modname, MODSIZE) == -1) { 223 tst_resm(TBROK, "Failed to create module entry" 224 " for %s", modname); 225 return 1; 226 } 227 return 0; 228 } 229 230 void cleanup2(void) 231 { 232 /* Remove loadable module entry */ 233 if (delete_module(modname) == -1) { 234 tst_brkm(TBROK, NULL, "Failed to delete module entry" 235 " for %s", modname); 236 } 237 } 238 239 /* 240 * setup() 241 * performs all ONE TIME setup for this test 242 */ 243 void setup(void) 244 { 245 246 tst_sig(NOFORK, DEF_HANDLER, cleanup); 247 248 tst_require_root(); 249 250 if (tst_kvercmp(2, 5, 48) >= 0) 251 tst_brkm(TCONF, NULL, "This test will not work on " 252 "kernels after 2.5.48"); 253 254 /* Check for nobody_uid user id */ 255 if ((ltpuser = getpwnam(nobody_uid)) == NULL) { 256 tst_brkm(TBROK, NULL, "Required user %s doesn't exists", 257 nobody_uid); 258 } 259 260 /* Initialize longmodname to LONGMODNAMECHAR character */ 261 memset(longmodname, LONGMODNAMECHAR, MODNAMEMAX - 1); 262 263 /* Pause if that option was specified 264 * TEST_PAUSE contains the code to fork the test with the -c option. 265 */ 266 TEST_PAUSE; 267 268 /* Get unique module name for each child process */ 269 if (sprintf(modname, "%s_%d", BASEMODNAME, getpid()) == -1) { 270 tst_brkm(TBROK, NULL, "Failed to initialize module name"); 271 } 272 } 273 274 /* 275 * cleanup() 276 * performs all ONE TIME cleanup for this test at 277 * completion or premature exit 278 */ 279 void cleanup(void) 280 { 281 } 282