• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   : query_module03
20  *
21  *    EXECUTED BY       : root / superuser
22  *
23  *    TEST TITLE        : Checking error conditions for query_module(2)
24  *
25  *    TEST CASE TOTAL   : 4
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. query_module(2) returns -1 and sets errno to EFAULT for module name
36  *	   argument outside program's accessible address space.
37  *	2. query_module(2) returns -1 and sets errno to EFAULT for return size
38  *	   argument outside program's accessible address space.
39  *	3. query_module(2) returns -1 and sets errno to EFAULT for output buffer
40  *	   argument outside program's accessible address space.
41  *	4. query_module(2) returns -1 and sets errno to ENOSPC for too small
42  *	   buffer size.
43  *
44  *	Setup:
45  *	  Setup signal handling.
46  *	  Test caller is superuser
47  *	  Set expected errnos for logging
48  *	  Pause for SIGUSR1 if option specified.
49  *
50  *	Test:
51  *	 Loop if the proper options are given.
52  *	  Execute system call
53  *	  Check return code and error number, if matching,
54  *		Issue PASS message
55  *	  Otherwise,
56  *		Issue FAIL message
57  *
58  *	Cleanup:
59  *	  Print errno log and/or timing stats if options given
60  *
61  * USAGE:  <for command-line>
62  *  query_module03 [-c n] [-e] [-f] [-h] [-i n] [-I x] [-p] [-P x] [-t]
63  *		where,  -c n : Run n copies concurrently.
64  *			-e   : Turn on errno logging.
65  *			-f   : Turn off functional testing
66  *			-h   : Show help screen
67  *			-i n : Execute test n times.
68  *			-I x : Execute test for x seconds.
69  *			-p   : Pause for SIGUSR1 before starting
70  *			-P x : Pause for x seconds between iterations.
71  *			-t   : Turn on syscall timing.
72  *
73  * RESTRICTIONS
74  *	-c option has no effect for this testcase, even if used allows only
75  *	one instance to run at a time.
76  *
77  * CHANGES
78  *
79  * 12/03/02 Added "force" to insmod to ignore kernel version.
80  *          -Robbie Williamson <robbiew@us.ibm.com>
81  *
82  ****************************************************************/
83 
84 #include <unistd.h>
85 #include <errno.h>
86 #include <pwd.h>
87 #include <sys/types.h>
88 #include <unistd.h>
89 #include <limits.h>
90 #include <asm/atomic.h>
91 #include <linux/module.h>
92 #include <sys/mman.h>
93 #include "test.h"
94 
95 #ifndef PAGE_SIZE
96 #define PAGE_SIZE sysconf(_SC_PAGE_SIZE)
97 #endif
98 
99 #define EXP_RET_VAL	-1
100 #define DUMMY_MOD	"dummy_query_mod"
101 #define SMALLBUFSIZE	1
102 
103 struct test_case_t {		/* test case structure */
104 	char *modname;
105 	int which;
106 	void *buf;
107 	size_t bufsize;
108 	size_t *ret_size;
109 	int experrno;		/* expected errno */
110 	char *desc;
111 	int (*setup) (void);
112 	void (*cleanup) (void);
113 };
114 
115 char *TCID = "query_module03";
116 
117 static int testno;
118 static char out_buf[PAGE_SIZE];
119 static size_t ret_size;
120 
121 char *bad_addr = 0;
122 
123 static void setup(void);
124 static void cleanup(void);
125 static int setup1(void);
126 static void cleanup1(void);
127 
128 static struct test_case_t tdat[] = {
129 
130 	{(char *)-1, QM_MODULES, (void *)out_buf, sizeof(out_buf), &ret_size,
131 	 EFAULT, "results for module name argument outside program's "
132 	 "accessible address space", NULL, NULL}
133 	,
134 
135 	{NULL, QM_MODULES, (void *)out_buf, sizeof(out_buf), (size_t *) - 1,
136 	 EFAULT, "results for return size argument outside program's "
137 	 "accessible address space", NULL, NULL}
138 	,
139 
140 	{NULL, QM_MODULES, (void *)-1, sizeof(out_buf), &ret_size, EFAULT,
141 	 "results for output buffer argument outside program's "
142 	 "accessible address space", setup1, cleanup1}
143 	,
144 
145 	{NULL, QM_MODULES, (void *)out_buf, SMALLBUFSIZE, &ret_size, ENOSPC,
146 	 "results for too small buffer size", setup1, cleanup1},
147 };
148 
149 int TST_TOTAL = sizeof(tdat) / sizeof(tdat[0]);
150 
main(int argc,char ** argv)151 int main(int argc, char **argv)
152 {
153 	int lc;
154 
155 	tst_parse_opts(argc, argv, NULL, NULL);
156 
157 	tst_tmpdir();
158 	setup();
159 
160 	for (lc = 0; TEST_LOOPING(lc); lc++) {
161 		/* reset tst_count in case we are looping */
162 		tst_count = 0;
163 
164 		for (testno = 0; testno < TST_TOTAL; ++testno) {
165 
166 			if ((tdat[testno].setup) && (tdat[testno].setup())) {
167 				/* setup() failed, skip this test */
168 				continue;
169 			}
170 			TEST(query_module(tdat[testno].modname,
171 					  tdat[testno].which, tdat[testno].buf,
172 					  tdat[testno].bufsize,
173 					  tdat[testno].ret_size));
174 			if ((TEST_RETURN == EXP_RET_VAL) &&
175 			    (TEST_ERRNO == tdat[testno].experrno)) {
176 				tst_resm(TPASS, "Expected %s, errno: %d",
177 					 tdat[testno].desc, TEST_ERRNO);
178 			} else {
179 				tst_resm(TFAIL, "Unexpected %s ; returned"
180 					 " %d (expected %d), errno %d (expected"
181 					 " %d)", tdat[testno].desc,
182 					 TEST_RETURN, EXP_RET_VAL,
183 					 TEST_ERRNO, tdat[testno].experrno);
184 			}
185 			if (tdat[testno].cleanup) {
186 				tdat[testno].cleanup();
187 			}
188 		}
189 	}
190 	cleanup();
191 	tst_exit();
192 }
193 
setup1(void)194 int setup1(void)
195 {
196 	char cmd[80];
197 
198 	if (sprintf(cmd, "cp `which %s.o` ./", DUMMY_MOD) == -1) {
199 		tst_resm(TBROK, "sprintf failed");
200 		return 1;
201 	}
202 	if (system(cmd) != 0) {
203 		tst_resm(TBROK, "Failed to copy %s module", DUMMY_MOD);
204 		return 1;
205 	}
206 
207 	/* Should use force to ignore kernel version & insure loading  */
208 	/* -RW                                                         */
209 	/* if (sprintf(cmd, "insmod %s.o", DUMMY_MOD) == -1) {         */
210 	if (sprintf(cmd, "insmod --force -q %s.o >/dev/null 2>&1", DUMMY_MOD) ==
211 	    -1) {
212 		tst_resm(TBROK, "sprintf failed");
213 		return 1;
214 	}
215 	if (system(cmd) != 0) {
216 		tst_resm(TBROK, "Failed to load %s module", DUMMY_MOD);
217 		return 1;
218 	}
219 	return 0;
220 }
221 
cleanup1(void)222 void cleanup1(void)
223 {
224 	/* Remove the loadable module - DUMMY_MOD */
225 	if (system("rmmod " DUMMY_MOD) != 0) {
226 		tst_brkm(TBROK, cleanup, "Failed to unload module %s",
227 			 DUMMY_MOD);
228 	}
229 }
230 
231 /*
232  * setup()
233  *	performs all ONE TIME setup for this test
234  */
setup(void)235 void setup(void)
236 {
237 
238 	tst_sig(FORK, DEF_HANDLER, cleanup);
239 
240 	tst_require_root();
241 
242 	if (tst_kvercmp(2, 5, 48) >= 0)
243 		tst_brkm(TCONF, NULL, "This test will not work on "
244 			 "kernels after 2.5.48");
245 
246 	/* Pause if that option was specified
247 	 * TEST_PAUSE contains the code to fork the test with the -c option.
248 	 */
249 	TEST_PAUSE;
250 
251 	bad_addr = mmap(0, 1, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
252 	if (bad_addr == MAP_FAILED) {
253 		tst_brkm(TBROK, cleanup, "mmap failed");
254 	}
255 	tdat[0].modname = bad_addr;
256 	tdat[2].buf = (void *)bad_addr;
257 
258 }
259 
260 /*
261  * cleanup()
262  *	performs all ONE TIME cleanup for this test at
263  *	completion or premature exit
264  */
cleanup(void)265 void cleanup(void)
266 {
267 	/*
268 	 * print timing stats if that option was specified.
269 	 * print errno log if that option was specified.
270 	 */
271 	tst_rmdir();
272 }
273