blob: dba8bea0c0a824e824e79cbfacf40d7f77ac18f0 [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
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000018 */
19
20/*
21 * Name: vfork01
22 *
23 * Test Description:
24 * Fork a process using vfork() and verify that, the attribute values like
25 * euid, ruid, suid, egid, rgid, sgid, umask, inode and device number of
subrata_modak4bb656a2009-02-26 12:02:09 +000026 * root and current working directories are same as that of the parent
plars865695b2001-08-27 22:15:12 +000027 * process.
subrata_modak56207ce2009-03-23 13:35:39 +000028 * $
plars865695b2001-08-27 22:15:12 +000029 * Expected Result:
30 * The attribute values like euid, ruid, suid, egid, rgid, sgid, umask, inode
31 * and device number of root and current working directory of the parent and
32 * child processes should be equal.
33 *
34 * Algorithm:
35 * Setup:
36 * Setup signal handling.
37 * Pause for SIGUSR1 if option specified.
38 *
39 * Test:
40 * Loop if the proper options are given.
41 * Execute system call
42 * Check return code, if system call failed (return=-1)
43 * Log the errno and Issue a FAIL message.
44 * Otherwise,
subrata_modakbdbaec52009-02-26 12:14:51 +000045 * Verify the Functionality of system call
plars865695b2001-08-27 22:15:12 +000046 * if successful,
47 * Issue Functionality-Pass message.
48 * Otherwise,
49 * Issue Functionality-Fail message.
50 * Cleanup:
51 * Print errno log and/or timing stats if options given
52 *
53 * Usage: <for command-line>
54 * vfork01 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
55 * where, -c n : Run n copies concurrently.
56 * -e : Turn on errno logging.
57 * -f : Turn off functionality Testing.
58 * -i n : Execute test n times.
59 * -I x : Execute test for x seconds.
60 * -P x : Pause for x seconds between iterations.
61 * -t : Turn on syscall timing.
62 *
63 * History
64 * 07/2001 John George
65 * -Ported
66 *
67 * Restrictions:
68 * None.
69 *
70 */
71
vapierbed036a2006-05-26 06:48:55 +000072#define _GNU_SOURCE 1
plars865695b2001-08-27 22:15:12 +000073#include <stdio.h>
74#include <sys/types.h>
75#include <errno.h>
76#include <unistd.h>
77#include <fcntl.h>
78#include <string.h>
79#include <signal.h>
plars74948ad2002-11-14 16:16:14 +000080#include <unistd.h>
plars865695b2001-08-27 22:15:12 +000081#include <sys/stat.h>
82#include <sys/wait.h>
83
84#include "test.h"
plars865695b2001-08-27 22:15:12 +000085
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020086char *TCID = "vfork01";
87int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000088
89/* Variables to hold parent/child eff/real/saved uid/gid values */
subrata_modak56207ce2009-03-23 13:35:39 +000090uid_t Peuid, Ceuid, Csuid, Psuid, Pruid, Cruid;
91gid_t Pegid, Cegid, Psgid, Csgid, Prgid, Crgid;
92mode_t Pumask, Cumask;
plars865695b2001-08-27 22:15:12 +000093
subrata_modak56207ce2009-03-23 13:35:39 +000094char *Pcwd, *Ccwd; /*
plars865695b2001-08-27 22:15:12 +000095 * pathname of working directory of
96 * child/parent process.
97 */
98/* stat structure to hold directory/inode information for parent/child */
99struct stat StatPbuf;
100struct stat StatCbuf;
101struct stat Stat_cwd_Pbuf;
102struct stat Stat_cwd_Cbuf;
103
104void setup(); /* Main setup function of test */
105void cleanup(); /* cleanup function for the test */
106
subrata_modak56207ce2009-03-23 13:35:39 +0000107int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000108{
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200109 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200110 const char *msg;
plars865695b2001-08-27 22:15:12 +0000111 pid_t cpid; /* process id of the child process */
112 int exit_status; /* exit status of child process */
subrata_modak56207ce2009-03-23 13:35:39 +0000113
Garrett Cooper45e285d2010-11-22 12:19:25 -0800114 msg = parse_opts(ac, av, NULL, NULL);
115 if (msg != NULL) {
plars865695b2001-08-27 22:15:12 +0000116 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Garrett Cooper2c282152010-12-16 00:55:50 -0800117
plars865695b2001-08-27 22:15:12 +0000118 }
119
plars865695b2001-08-27 22:15:12 +0000120 setup();
121
plars865695b2001-08-27 22:15:12 +0000122 for (lc = 0; TEST_LOOPING(lc); lc++) {
Garrett Cooper2c282152010-12-16 00:55:50 -0800123
Caspar Zhangd59a6592013-03-07 14:59:12 +0800124 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000125
subrata_modak4bb656a2009-02-26 12:02:09 +0000126 /*
plars865695b2001-08-27 22:15:12 +0000127 * Call vfork(2) to create a child process without
128 * fully copying the address space of parent.
129 */
130 TEST(vfork());
131
plars865695b2001-08-27 22:15:12 +0000132 if ((cpid = TEST_RETURN) == -1) {
plars865695b2001-08-27 22:15:12 +0000133 tst_resm(TFAIL, "vfork() Failed, errno=%d : %s",
134 TEST_ERRNO, strerror(TEST_ERRNO));
subrata_modak56207ce2009-03-23 13:35:39 +0000135 } else if (cpid == 0) { /* Child process */
plars865695b2001-08-27 22:15:12 +0000136 /*
Cyril Hrubise38b9612014-06-02 17:20:57 +0200137 * Get the euid, ruid, egid, rgid, umask value
138 * and the current working directory of the
139 * child process
plars865695b2001-08-27 22:15:12 +0000140 */
Cyril Hrubise38b9612014-06-02 17:20:57 +0200141 if (getresuid(&Cruid, &Ceuid, &Csuid) < 0) {
142 tst_resm(TFAIL, "getresuid() fails to "
143 "get real/eff./saved uid of "
144 "child process");
145 _exit(1);
plars865695b2001-08-27 22:15:12 +0000146 }
Cyril Hrubise38b9612014-06-02 17:20:57 +0200147
148 if (getresgid(&Crgid, &Cegid, &Csgid) < 0) {
149 tst_resm(TFAIL, "getresgid() fails to "
150 "get real/eff./saved gid of "
151 "child process");
152 _exit(1);
153 }
154
155 /*
156 * Get the file mode creation mask value of
157 * child process by setting value zero and
158 * restore the previous mask value.
159 */
160 Cumask = umask(0);
161
162 /*
163 * Restore the process mask of child to
164 * previous value.
165 */
166 umask(Cumask);
167
168 /*
169 * Get the pathname of current working
170 * directory for the child process.
171 */
172 if ((Ccwd = (char *)getcwd(NULL,
173 BUFSIZ)) == NULL) {
174 tst_resm(TFAIL, "getcwd failed for the "
175 "child process");
176 _exit(1);
177 }
178
179 /*
180 * Get the device number and the inode
181 * number of "/" directory for the child
182 * process.
183 */
184 if (stat("/", &StatCbuf) < 0) {
185 tst_resm(TFAIL, "stat(2) failed to get "
186 "info. of'/' in the child "
187 "process");
188 _exit(1);
189 }
190
191 /*
192 * Get the device/inode number of "."
193 * (working directory) for the child process.
194 */
195 if (stat(Ccwd, &Stat_cwd_Cbuf) < 0) {
196 tst_resm(TFAIL, "stat(2) failed to get "
197 "info. of working irectory in "
198 "the child");
199 _exit(1);
200 }
201
202 /* Now, do the actual comparision */
203 if (Peuid != Ceuid || Pegid != Cegid ||
204 Psuid != Csuid || Psgid != Csgid ||
205 Pruid != Cruid || Prgid != Crgid ||
206 Pumask != Cumask) {
207 tst_resm(TFAIL, "Attribute values of "
208 "parent and child don't match");
209 _exit(1);
210 } else {
211 tst_resm(TINFO, "Attribute values of "
212 "parent and child match");
213 }
214
215 /* Check for the same working directories */
216 if (strcmp(Pcwd, Ccwd) != 0) {
217 tst_resm(TFAIL, "Working directories "
218 "of parent and child don't "
219 "match");
220 _exit(1);
221 } else {
222 tst_resm(TINFO, "Working directories "
223 "of parent and child match");
224 }
225
226 /*
227 * Check for the same device/inode number of
228 * '/' directory.
229 */
230 if ((StatPbuf.st_ino != StatCbuf.st_ino) ||
231 (StatPbuf.st_dev != StatCbuf.st_dev)) {
232 tst_resm(TFAIL, "Device/inode number "
233 "of parent and childs '/' "
234 " don't match");
235 _exit(1);
236 } else {
237 tst_resm(TINFO, "Device/inode number "
238 "of parent and childs '/' "
239 "match");
240 }
241
242 /*
243 * Check for the same device and inode number
244 * of "." (current working directory.
245 */
246 if ((Stat_cwd_Pbuf.st_ino !=
247 Stat_cwd_Cbuf.st_ino) ||
248 (Stat_cwd_Pbuf.st_dev !=
249 Stat_cwd_Cbuf.st_dev)) {
250 tst_resm(TFAIL, "Device/inode number "
251 "of parent and childs '.' "
252 "don't match");
253 _exit(1);
254 } else {
255 tst_resm(TINFO, "Device/inode number "
256 "of parent and childs '.' "
257 "don't match");
258 }
259
260 /*
261 * Exit with normal exit code if everything
262 * fine
263 */
264 _exit(0);
265
plars865695b2001-08-27 22:15:12 +0000266 } else { /* parent process */
267 /*
268 * Let the parent process wait till child completes
269 * its execution.
270 */
271 wait(&exit_status);
272
273 /* Check for the exit status of child process */
274 if (WEXITSTATUS(exit_status) == 0) {
subrata_modak56207ce2009-03-23 13:35:39 +0000275 tst_resm(TPASS, "Call of vfork() successful");
plars865695b2001-08-27 22:15:12 +0000276 } else if (WEXITSTATUS(exit_status) == 1) {
subrata_modak56207ce2009-03-23 13:35:39 +0000277 tst_resm(TFAIL,
plars865695b2001-08-27 22:15:12 +0000278 "Child process exited abnormally");
279 }
280 }
Caspar Zhangd59a6592013-03-07 14:59:12 +0800281 tst_count++; /* incr. TEST_LOOP counter */
Garrett Cooper2c282152010-12-16 00:55:50 -0800282 }
plars865695b2001-08-27 22:15:12 +0000283
plars865695b2001-08-27 22:15:12 +0000284 cleanup();
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800285 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800286}
plars865695b2001-08-27 22:15:12 +0000287
288/*
289 * void
290 * setup() - performs all ONE TIME setup for this test.
291 * This function gets real/effective/saved uid/gid, umask, the device/inode
292 * number of '/' and current working directory for the parent process.
293 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400294void setup(void)
plars865695b2001-08-27 22:15:12 +0000295{
Garrett Cooper2c282152010-12-16 00:55:50 -0800296
plars865695b2001-08-27 22:15:12 +0000297 tst_sig(FORK, DEF_HANDLER, cleanup);
298
plars865695b2001-08-27 22:15:12 +0000299 TEST_PAUSE;
300
301 /*
302 * Get the euid, ruid, egid, rgid, umask value
303 * and the current working directory of the parent process.
304 */
305 if (getresuid(&Pruid, &Peuid, &Psuid) < 0) {
306 tst_brkm(TFAIL, cleanup, "getresuid() fails to get "
subrata_modak56207ce2009-03-23 13:35:39 +0000307 "real/eff./saved uid of parent");
plars865695b2001-08-27 22:15:12 +0000308 }
309
310 if (getresgid(&Prgid, &Pegid, &Psgid) < 0) {
311 tst_brkm(TFAIL, cleanup, "getresgid() fails to get "
subrata_modak56207ce2009-03-23 13:35:39 +0000312 "real/eff./saved gid of parent");
plars865695b2001-08-27 22:15:12 +0000313 }
314
315 /* Get the process file mode creation mask by setting value 0 */
316 Pumask = umask(0);
subrata_modak56207ce2009-03-23 13:35:39 +0000317 umask(Pumask); /*
318 * Restore the mask value of the
319 * process.
320 */
plars865695b2001-08-27 22:15:12 +0000321 /*
322 * Get the pathname of current working directory of the parent
323 * process.
324 */
Garrett Cooper45e285d2010-11-22 12:19:25 -0800325 if ((Pcwd = (char *)getcwd(NULL, BUFSIZ)) == NULL) {
plars865695b2001-08-27 22:15:12 +0000326 tst_brkm(TFAIL, cleanup,
327 "getcwd failed for the parent process");
328 }
329
330 /*
subrata_modak56207ce2009-03-23 13:35:39 +0000331 * Get the device and inode number of root directory for the
plars865695b2001-08-27 22:15:12 +0000332 * parent process.
333 */
334 if (stat("/", &StatPbuf) == -1) {
335 tst_brkm(TFAIL, cleanup, "stat(2) failed to get info. of '/' "
subrata_modak56207ce2009-03-23 13:35:39 +0000336 "in parent process");
plars865695b2001-08-27 22:15:12 +0000337 }
338
339 /*
340 * Get the device number and the inode number of "." (current-
341 * working directory) for the parent process.
342 */
343 if (stat(Pcwd, &Stat_cwd_Pbuf) < 0) {
344 tst_brkm(TFAIL, cleanup, "stat(2) failed to get info. of "
subrata_modak56207ce2009-03-23 13:35:39 +0000345 "working directory in parent process");
plars865695b2001-08-27 22:15:12 +0000346 }
Garrett Cooper2c282152010-12-16 00:55:50 -0800347}
plars865695b2001-08-27 22:15:12 +0000348
349/*
350 * void
351 * cleanup() - performs all ONE TIME cleanup for this test at
352 * completion or premature exit.
353 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400354void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000355{
plars865695b2001-08-27 22:15:12 +0000356
Chris Dearmanec6edca2012-10-17 19:54:01 -0700357}