Home | History | Annotate | Download | only in create_module
      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