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	: reboot02
20  *
21  *
22  *    EXECUTED BY	: root / superuser
23  *
24  *    TEST TITLE	: Test checking for basic error conditions
25  *    				 for reboot(2)
26  *
27  *    TEST CASE TOTAL	: 2
28  *
29  *    AUTHOR		: Aniruddha Marathe <aniruddha.marathe@wipro.com>
30  *
31  *    SIGNALS
32  * 	Uses SIGUSR1 to pause before test if option set.
33  * 	(See the parse_opts(3) man page).
34  *
35  *    DESCRIPTION
36  *	This test case checks whether reboot(2) system call  returns
37  *	appropriate error number for invalid
38  *	flag parameter or invalid user.
39  *
40  * 	Setup:
41  *	  Setup signal handling.
42  *	  Pause for SIGUSR1 if option specified.
43  *	  For testing error on invalid user, change the effective uid
44  *
45  * 	Test:
46  *	  Loop if the proper options are given.
47  *	  Execute system call with invaid flag parameter
48  *	  and then for invalid user
49  *	  Check return code, if system call fails with errno == expected errno
50  *		Issue syscall passed with expected errno
51  *	  Otherwise,
52  *	  Issue syscall failed to produce expected errno
53  *
54  * 	Cleanup:
55  * 	  Do cleanup for the test.
56  * 	 $
57  * USAGE:  <for command-line>
58  *  reboot02 [-c n] [-e] [-i n] [-I x] [-p x] [-t] [-h] [-f] [-p]
59  *  where
60  *  	-c n: run n copies simultaneously
61  *	-e   : Turn on errno logging.
62  *	-i n : Execute test n times.
63  *	-I x : Execute test for x seconds.
64  *	-p   : Pause for SIGUSR1 before starting
65  *	-P x : Pause for x seconds between iterations.
66  *	-t   : Turn on syscall timing.
67  *
68  *RESTRICTIONS:
69  *for lib4 and lib5 reboot(2) system call is implemented as
70  *int reboot(int magic, int magic2, int flag, void *arg); This test case
71  *is written for int reboot(int flag); which is implemented under glibc
72  *Therefore this testcase may not work under libc4 and libc5 libraries
73  *****************************************************************************/
74 
75 #include <unistd.h>
76 #include <sys/reboot.h>
77 #include <errno.h>
78 #include <linux/reboot.h>
79 #include <pwd.h>
80 #include "test.h"
81 
82 #define INVALID_PARAMETER 100
83 
84 static void setup();
85 static void cleanup();
86 static int setup_test();
87 
88 char *TCID = "reboot02";
89 int TST_TOTAL = 2;
90 char nobody_uid[] = "nobody";
91 struct passwd *ltpuser;
92 
93 static struct test_case_t {
94 	char *err_desc;		/*error description */
95 	int exp_errno;		/* expected error number */
96 	char *exp_errval;	/*Expected errorvalue string */
97 } testcase[] = {
98 	{
99 	"Invalid flag", EINVAL, "EINVAL"}, {
100 	"Permission denied", EPERM, "EPERM "}
101 };
102 
main(int ac,char ** av)103 int main(int ac, char **av)
104 {
105 
106 	int lc, i;
107 
108 	tst_parse_opts(ac, av, NULL, NULL);
109 
110 	setup();
111 
112 	for (lc = 0; TEST_LOOPING(lc); lc++) {
113 
114 		for (i = 0; i < TST_TOTAL; i++) {
115 
116 			tst_count = 0;
117 			if (i == 0) {
118 				TEST(reboot(INVALID_PARAMETER));
119 			} else {
120 				/*change the user to nobody */
121 				if (setup_test() == 0) {
122 					TEST(reboot(LINUX_REBOOT_CMD_CAD_ON));
123 					/* Set effective user id back to root */
124 					if (seteuid(0) == -1) {
125 						tst_brkm(TBROK, cleanup,
126 							 "seteuid failed to "
127 							 "set the effective uid"
128 							 " to root");
129 						perror("seteuid");
130 					}
131 				} else {
132 					tst_resm(TWARN, "skipping the test");
133 					continue;
134 				}
135 			}
136 			/* check return code */
137 			if ((TEST_RETURN == -1)
138 			    && (TEST_ERRNO == testcase[i].exp_errno)) {
139 				tst_resm(TPASS,
140 					 "reboot(2) expected failure;"
141 					 " Got errno - %s : %s",
142 					 testcase[i].exp_errval,
143 					 testcase[i].err_desc);
144 			} else {
145 				tst_resm(TFAIL, "reboot(2) failed to produce"
146 					 " expected error; %d, errno"
147 					 ": %s and got %d",
148 					 testcase[i].exp_errno,
149 					 testcase[i].exp_errval, TEST_ERRNO);
150 			}
151 		}		/*End of TEST LOOPS */
152 	}
153 
154 	/*Clean up and exit */
155 	cleanup();
156 
157 	tst_exit();
158 }				/*End of main */
159 
160 /*
161  * setup_test() - This function sets the user as nobdy
162  */
setup_test(void)163 int setup_test(void)
164 {
165 	if ((ltpuser = getpwnam(nobody_uid)) == NULL) {
166 		tst_resm(TWARN, "\"nobody\" user not present. skipping test");
167 		return -1;
168 	}
169 	if (seteuid(ltpuser->pw_uid) == -1) {
170 		tst_resm(TWARN, "seteuid failed to "
171 			 "to set the effective uid to %d", ltpuser->pw_uid);
172 		perror("seteuid");
173 		return -1;
174 	}
175 	return 0;
176 }
177 
178 /* setup() - performs all ONE TIME setup for this test */
setup(void)179 void setup(void)
180 {
181 	tst_require_root();
182 
183 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
184 
185 	TEST_PAUSE;
186 
187 }
188 
189 /*
190 * cleanup() - Performs one time cleanup for this test at
191 * completion or premature exit
192 */
cleanup(void)193 void cleanup(void)
194 {
195 
196 }
197