• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *   Copyright (c) International Business Machines  Corp., 2001
4  *
5  *   This program is free software;  you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13  *   the GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program;  if not, write to the Free Software
17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 /*
21  * NAME
22  *	sysctl05.c
23  *
24  * DESCRIPTION
25  *	Testcase to check that sysctl(2) sets errno to EFAULT
26  *
27  * ALGORITHM
28  *	1. Call sysctl(2) with the address of sc_oldname outside the address
29  *	   space of the process, and expect EFAULT.
30  *	2. Call sysctl(2) with the address of sc_oldval outside the address
31  *	   space of the process, and expect EFAULT.
32  *
33  * USAGE:  <for command-line>
34  *  sysctl05 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
35  *     where,  -c n : Run n copies concurrently.
36  *             -e   : Turn on errno logging.
37  *             -i n : Execute test n times.
38  *             -I x : Execute test for x seconds.
39  *             -P x : Pause for x seconds between iterations.
40  *             -t   : Turn on syscall timing.
41  *
42  * HISTORY
43  *	07/2001 Ported by Wayne Boyer
44  *
45  * RESTRICTIONS
46  *	None
47  */
48 
49 #include "test.h"
50 #include <stdio.h>
51 #include <unistd.h>
52 #include <linux/unistd.h>
53 #include <linux/sysctl.h>
54 #include <linux/version.h>
55 #include <errno.h>
56 
57 char *TCID = "sysctl05";
58 
59 /* This is an older/deprecated syscall that newer arches are omitting */
60 #ifdef __NR_sysctl
61 
62 int TST_TOTAL = 2;
63 
sysctl(int * name,int nlen,void * oldval,size_t * oldlenp,void * newval,size_t newlen)64 int sysctl(int *name, int nlen, void *oldval, size_t * oldlenp,
65 	   void *newval, size_t newlen)
66 {
67 	struct __sysctl_args args =
68 	    { name, nlen, oldval, oldlenp, newval, newlen };
69 	return syscall(__NR__sysctl, &args);
70 }
71 
72 char osname[BUFSIZ];
73 size_t osnamelth;
74 
75 void setup(void);
76 void cleanup(void);
77 
78 struct testcases {
79 	char *desc;
80 	int name[2];
81 	int size;
82 	void *oldval;
83 	size_t *oldlen;
84 	void *newval;
85 	int newlen;
86 	int (*cleanup) ();
87 	int exp_retval;
88 	int exp_errno;
89 } testcases[] = {
90 	{
91 		"Test for EFAULT: invalid oldlen", {
92 	CTL_KERN, KERN_OSRELEASE},
93 		    2, osname, (void *)-1, NULL, 0, NULL, -1, EFAULT}, {
94 		"Test for EFAULT: invalid oldval", {
95 	CTL_KERN, KERN_VERSION},
96 		    2, (void *)-1, &osnamelth, NULL, 0, NULL, -1, EFAULT}
97 };
98 
99 #if !defined(UCLINUX)
100 
main(int ac,char ** av)101 int main(int ac, char **av)
102 {
103 	int lc;
104 	int i;
105 	int ret = 0;
106 
107 	tst_parse_opts(ac, av, NULL, NULL);
108 
109 	setup();
110 
111 	for (lc = 0; TEST_LOOPING(lc); lc++) {
112 
113 		/* reset tst_count in case we are looping */
114 		tst_count = 0;
115 
116 		for (i = 0; i < TST_TOTAL; ++i) {
117 
118 			osnamelth = sizeof(osname);
119 
120 			TEST(sysctl(testcases[i].name, testcases[i].size,
121 				    testcases[i].oldval, testcases[i].oldlen,
122 				    testcases[i].newval, testcases[i].newlen));
123 
124 			if (TEST_RETURN != testcases[i].exp_retval) {
125 				tst_resm(TFAIL, "sysctl(2) returned unexpected "
126 					 "retval, expected: %d, got: %d",
127 					 testcases[i].exp_retval, ret);
128 				continue;
129 			}
130 
131 			if (TEST_ERRNO == ENOSYS) {
132 				tst_resm(TCONF,
133 					 "You may need to make CONFIG_SYSCTL_SYSCALL=y"
134 					 " to your kernel config.");
135 			} else if (TEST_ERRNO != testcases[i].exp_errno) {
136 				tst_resm(TFAIL, "sysctl(2) returned unexpected "
137 					 "errno, expected: %d, got: %d",
138 					 testcases[i].exp_errno, errno);
139 			} else {
140 				tst_resm(TPASS, "sysctl(2) set errno correctly "
141 					 "to %d", testcases[i].exp_errno);
142 			}
143 
144 			if (testcases[i].cleanup) {
145 				(void)testcases[i].cleanup();
146 			}
147 		}
148 	}
149 	cleanup();
150 
151 	tst_exit();
152 }
153 
154 #else
155 
main(void)156 int main(void)
157 {
158 	tst_resm(TINFO, "test is not available on uClinux");
159 	tst_exit();
160 }
161 
162 #endif /* if !defined(UCLINUX) */
163 
164 /*
165  * setup() - performs all ONE TIME setup for this test.
166  */
setup(void)167 void setup(void)
168 {
169 
170 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
171 
172 	TEST_PAUSE;
173 }
174 
175 /*
176  * cleanup() - performs all ONE TIME cleanup for this test at
177  *	       completion or premature exit.
178  */
cleanup(void)179 void cleanup(void)
180 {
181 
182 }
183 
184 #else
185 int TST_TOTAL = 0;
186 
main(void)187 int main(void)
188 {
189 
190 	tst_brkm(TCONF, NULL,
191 		 "This test needs a kernel that has sysctl syscall.");
192 }
193 #endif
194