blob: 9befbddb3078ece14915d7530e1d899d74c6c202 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20/*
21 * NAME
22 * chroot03.c
23 *
24 * DESCRIPTION
25 * Testcase to test whether chroot(2) sets errno correctly.
26 *
27 * CALLS
28 * chroot(2)
29 *
30 * ALGORITHM
31 * 1. Test for ENAMETOOLONG:
32 * Create a bad directory name with length more than
33 * VFS_MAXNAMELEN (Linux kernel variable), and pass it as the
34 * path to chroot(2).
35 *
36 * 2. Test for ENOENT:
37 * Attempt to chroot(2) on a non-existent directory
38 *
39 * 3. Test for ENOTDIR:
40 * Attempt to chdir(2) on a file.
41 *
42 * 4. Test for EFAULT:
43 * The pathname parameter to chroot() points to an invalid address,
44 * chroot(2) fails with EPERM.
45 *
46 * USAGE: <for command-line>
47 * chroot03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
48 * where, -c n : Run n copies concurrently.
49 * -e : Turn on errno logging.
50 * -i n : Execute test n times.
51 * -I x : Execute test for x seconds.
52 * -P x : Pause for x seconds between iterations.
53 * -t : Turn on syscall timing.
54 *
55 * HISTORY
56 * 07/2001 Ported by Wayne Boyer
57 *
58 * RESTRICTIONS
59 * None
60 */
61
62#include <stdio.h>
63#include <errno.h>
64#include <sys/stat.h>
65#include <test.h>
66#include <usctest.h>
67
68char *TCID = "chroot03";
69int TST_TOTAL = 4;
70extern int Tst_count;
71
72int fd;
73char fname[255];
74char good_dir[100] = "/tmp/testdir";
75char bad_dir[] = "abcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyz";
76
77int exp_enos[]={ENAMETOOLONG, ENOENT, ENOTDIR, EFAULT, 0};
78
79struct test_case_t {
80 char *dir;
81 int error;
82} TC[] = {
83 /*
84 * to test whether chroot() is setting ENAMETOOLONG if the
85 * pathname is more than VFS_MAXNAMELEN
86 */
87 {bad_dir, ENAMETOOLONG},
88
89 /*
90 * to test whether chroot() is setting ENOTDIR if the argument
91 * is not a directory.
92 */
93 {fname, ENOTDIR},
94
95 /*
96 * to test whether chroot() is setting ENOENT if the directory
97 * does not exist.
98 */
99 {good_dir, ENOENT},
100
101 /*
102 * attempt to chroot to a path pointing to an invalid address
103 * and expect EFAULT as errno
104 */
105 {(char *)-1, EFAULT}
106};
107
108void setup(void);
109void cleanup(void);
110
111main(int ac, char **av)
112{
113 int lc; /* loop counter */
114 int i;
115 char *msg; /* message returned from parse_opts */
116
117 /* parse standard options */
118 if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
119 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
120 }
121
122 setup();
123
124 /* set up the expected errnos */
125 TEST_EXP_ENOS(exp_enos);
126
127 /* check looping state if -i option is given */
128 for (lc = 0; TEST_LOOPING(lc); lc++) {
129 /* reset Tst_count in case we are looping */
130 Tst_count = 0;
131
132 /* loop through the test cases */
133 for (i = 0; i < TST_TOTAL; i++) {
134
135 TEST(chroot(TC[i].dir));
136
137 if (TEST_RETURN != -1) {
138 tst_resm(TFAIL, "call succeeded unexpectedly");
139 continue;
140 }
141
142 TEST_ERROR_LOG(TEST_ERRNO);
143
144 if (TEST_ERRNO == TC[i].error) {
145 tst_resm(TPASS, "expected failure - "
146 "errno = %d : %s", TEST_ERRNO,
147 strerror(TEST_ERRNO));
148 } else {
149 tst_resm(TFAIL, "unexpected error - %d : %s - "
150 "expected %d", TEST_ERRNO,
151 strerror(TEST_ERRNO), TC[i].error);
152 }
153 }
154 }
155 cleanup();
156
157 /*NOTREACHED*/
158}
159
160/*
161 * setup() - performs all ONE TIME setup for this test.
162 */
163void
164setup()
165{
166 /* capture signals */
167 tst_sig(NOFORK, DEF_HANDLER, cleanup);
168
169 /* Pause if that option was specified */
170 TEST_PAUSE;
171
172 /* make a temporary directory and cd to it */
173 tst_tmpdir();
174
175 /*
176 * create a file and use it to test whether chroot() is setting
177 * ENOTDIR if the argument is not a directory.
178 */
179 (void) sprintf(fname, "tfile_%d", getpid());
180 if ((fd = creat(fname, 0777)) == -1) {
181 tst_brkm(TBROK, cleanup, "Failed to creat a temp file");
182 }
183
184 /*
185 * set up good_dir to test whether chroot() is setting ENOENT if the
186 * directory does not exist.
187 */
188 (void)sprintf(good_dir, "%s.%d", good_dir, getpid());
189}
190
191
192/*
193 * cleanup() - performs all ONE TIME cleanup for this test at
194 * completion or premature exit.
195 */
196void
197cleanup()
198{
199 /*
200 * print timing stats if that option was specified.
201 * print errno log if that option was specified.
202 */
203 TEST_CLEANUP;
204
205 /* delete the test directory created in setup() */
206 tst_rmdir();
207
208 /* exit with return code appropriate for results */
209 tst_exit();
210}