Home | History | Annotate | Download | only in sysctl
      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 
     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 
    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 
    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  */
    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  */
    179 void cleanup(void)
    180 {
    181 
    182 }
    183 
    184 #else
    185 int TST_TOTAL = 0;
    186 
    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