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  *	rename08
23  *
24  * DESCRIPTION
25  *	This test will verify that rename(2) syscall failed in EFAULT
26  *
27  * ALGORITHM
28  *	Setup:
29  *		Setup signal handling.
30  *		Create temporary directory.
31  *		Pause for SIGUSR1 if option specified.
32  *		Create a valid file to use in the rename() call.
33  *
34  *	Test:
35  *		Loop if the proper options are given.
36  *              1.  "old" is a valid file, newpath points to address
37  *                   outside allocated address space
38  *                  rename the "old" to the "new" file
39  *                  verify rename() failed with error EFAULT
40  *
41  *              2.  "old" points to address outside allocated address space
42  *                  ,"new" is a valid file
43  *                  rename the "old" to the "new"
44  *                  verify rename() failed with error EFAULT
45  *
46  *              3.  oldpath and newpath are all NULL
47  *                  try to rename NULL to NULL
48  *                  verify rename() failed with error EFAULT
49  *	Cleanup:
50  *		Print errno log and/or timing stats if options given
51  *		Delete the temporary directory created.*
52  * USAGE
53  *	rename08 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
54  *	where,  -c n : Run n copies concurrently.
55  *		-e   : Turn on errno logging.
56  *		-i n : Execute test n times.
57  *		-I x : Execute test for x seconds.
58  *		-P x : Pause for x seconds between iterations.
59  *		-t   : Turn on syscall timing.
60  *
61  * HISTORY
62  *	07/2001 Ported by Wayne Boyer
63  *
64  * RESTRICTIONS
65  *	None.
66  */
67 #include <sys/types.h>
68 #include <fcntl.h>
69 #include <sys/mman.h>
70 #include <unistd.h>
71 #include <errno.h>
72 
73 #include "test.h"
74 
75 void setup();
76 void cleanup();
77 
78 char *TCID = "rename08";
79 
80 char *bad_addr = 0;
81 
82 int fd;
83 char fname[255];
84 
85 struct test_case_t {
86 	char *fd;
87 	char *fd2;
88 	int error;
89 } TC[] = {
90 #if !defined(UCLINUX)
91 	/* "new" file is invalid - EFAULT */
92 	{
93 	fname, (char *)-1, EFAULT},
94 	    /* "old" file is invalid - EFAULT */
95 	{
96 	(char *)-1, fname, EFAULT},
97 #endif
98 	    /* both files are NULL - EFAULT */
99 	{
100 	NULL, NULL, EFAULT}
101 };
102 
103 int TST_TOTAL = ARRAY_SIZE(TC);
104 
main(int ac,char ** av)105 int main(int ac, char **av)
106 {
107 	int lc;
108 	int i;
109 
110 	/*
111 	 * parse standard options
112 	 */
113 	tst_parse_opts(ac, av, NULL, NULL);
114 
115 	setup();
116 
117 	/*
118 	 * check looping state if -i option given
119 	 */
120 	for (lc = 0; TEST_LOOPING(lc); lc++) {
121 
122 		tst_count = 0;
123 
124 		/* loop through the test cases */
125 		for (i = 0; i < TST_TOTAL; i++) {
126 
127 			TEST(rename(TC[i].fd, TC[i].fd2));
128 
129 			if (TEST_RETURN != -1) {
130 				tst_resm(TFAIL, "call succeeded unexpectedly");
131 				continue;
132 			}
133 
134 			if (TEST_ERRNO == TC[i].error) {
135 				tst_resm(TPASS, "expected failure - "
136 					 "errno = %d : %s", TEST_ERRNO,
137 					 strerror(TEST_ERRNO));
138 			} else {
139 				tst_resm(TFAIL, "unexpected error - %d : %s - "
140 					 "expected %d", TEST_ERRNO,
141 					 strerror(TEST_ERRNO), TC[i].error);
142 			}
143 		}
144 	}
145 
146 	cleanup();
147 	tst_exit();
148 
149 }
150 
151 /*
152  * setup() - performs all ONE TIME setup for this test.
153  */
setup(void)154 void setup(void)
155 {
156 
157 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
158 
159 	TEST_PAUSE;
160 
161 	/* Create a temporary directory and make it current. */
162 	tst_tmpdir();
163 
164 	sprintf(fname, "./tfile_%d", getpid());
165 
166 	SAFE_TOUCH(cleanup, fname, 0700, NULL);
167 
168 #if !defined(UCLINUX)
169 	bad_addr = mmap(0, 1, PROT_NONE,
170 			MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
171 	if (bad_addr == MAP_FAILED) {
172 		tst_brkm(TBROK, cleanup, "mmap failed");
173 	}
174 	TC[0].fd2 = bad_addr;
175 	TC[1].fd = bad_addr;
176 #endif
177 }
178 
179 /*
180  * cleanup() - performs all ONE TIME cleanup for this test at
181  *              completion or premature exit.
182  */
cleanup(void)183 void cleanup(void)
184 {
185 
186 	/*
187 	 * Remove the temporary directory.
188 	 */
189 	tst_rmdir();
190 }
191