blob: 4eae8db66ce4e4b3bf2f08e457c1ec5f84387a51 [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/*
nstrazfa31d552002-05-14 16:50:06 +000021 * Test Name: mknod08
plars865695b2001-08-27 22:15:12 +000022 *
23 * Test Description:
subrata_modak4bb656a2009-02-26 12:02:09 +000024 * Verify that mknod(2) succeeds when used to create a filesystem
plars865695b2001-08-27 22:15:12 +000025 * node on a directory without set group-ID bit set. The node created
26 * should not have set group-ID bit set and its gid should be equal to that
27 * of its parent directory.
28 *
29 * Expected Result:
30 * mknod() should return value 0 on success and node created should not
31 * have set group-ID bit set.
32 *
33 * Algorithm:
34 * Setup:
35 * Setup signal handling.
36 * Create temporary directory.
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)
subrata_modak56207ce2009-03-23 13:35:39 +000043 * Log the errno and Issue a FAIL message.
plars865695b2001-08-27 22:15:12 +000044 * Otherwise,
subrata_modak56207ce2009-03-23 13:35:39 +000045 * Verify the Functionality of system call
plars865695b2001-08-27 22:15:12 +000046 * if successful,
subrata_modak56207ce2009-03-23 13:35:39 +000047 * Issue Functionality-Pass message.
plars865695b2001-08-27 22:15:12 +000048 * Otherwise,
49 * Issue Functionality-Fail message.
50 * Cleanup:
51 * Print errno log and/or timing stats if options given
52 * Delete the temporary directory created.
53 *
54 * Usage: <for command-line>
nstrazfa31d552002-05-14 16:50:06 +000055 * mknod08 [-c n] [-e] [-f] [-i n] [-I x] [-P x] [-t]
plars865695b2001-08-27 22:15:12 +000056 * where, -c n : Run n copies concurrently.
57 * -e : Turn on errno logging.
58 * -f : Turn off functionality Testing.
59 * -i n : Execute test n times.
60 * -I x : Execute test for x seconds.
61 * -P x : Pause for x seconds between iterations.
62 * -t : Turn on syscall timing.
63 *
64 * HISTORY
65 * 07/2001 Ported by Wayne Boyer
66 *
67 * RESTRICTIONS:
68 * This test should be run by 'super-user' (root) only.
69 *
70 */
71
72#include <stdio.h>
73#include <stdlib.h>
74#include <unistd.h>
75#include <errno.h>
76#include <string.h>
77#include <signal.h>
78#include <pwd.h>
79#include <sys/types.h>
80#include <sys/stat.h>
81
82#include "test.h"
83#include "usctest.h"
84
85#define LTPUSER "nobody"
86#define MODE_RWX S_IFIFO | S_IRWXU | S_IRWXG | S_IRWXO
87#define DIR_TEMP "testdir_1"
88#define TNODE "tnode_%d"
89
90struct stat buf; /* struct. to hold stat(2) o/p contents */
91struct passwd *user1; /* struct. to hold getpwnam(3) o/p contents */
92
subrata_modak56207ce2009-03-23 13:35:39 +000093char *TCID = "mknod08"; /* Test program identifier. */
plars865695b2001-08-27 22:15:12 +000094int TST_TOTAL = 1; /* Total number of test cases. */
95char node_name[PATH_MAX]; /* buffer to hold node name created */
subrata_modak56207ce2009-03-23 13:35:39 +000096extern int Tst_count; /* Test Case counter for tst_* routines */
plars865695b2001-08-27 22:15:12 +000097
98gid_t group1_gid, group2_gid, mygid; /* user and process group id's */
99uid_t save_myuid, user1_uid; /* user and process user id's */
100pid_t mypid; /* process id */
101
102void setup(); /* setup function for the test */
103void cleanup(); /* cleanup function for the test */
104
subrata_modak56207ce2009-03-23 13:35:39 +0000105int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000106{
107 int lc; /* loop counter */
108 int fflag; /* functionality flag variable */
109 char *msg; /* message returned from parse_opts */
110
111 /* Parse standard options given to run the test. */
Garrett Cooper45e285d2010-11-22 12:19:25 -0800112 msg = parse_opts(ac, av, NULL, NULL);
113 if (msg != NULL) {
plars865695b2001-08-27 22:15:12 +0000114 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
115 tst_exit();
116 }
117
118 /* Perform global setup for test */
119 setup();
120
121 /* Check looping state if -i option given */
122 for (lc = 0; TEST_LOOPING(lc); lc++) {
123 /* Reset Tst_count in case we are looping. */
subrata_modak56207ce2009-03-23 13:35:39 +0000124 Tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000125
126 /*
127 * Call mknod() to creat a node on a directory without
128 * set group-ID (sgid) bit set.
129 */
130 TEST(mknod(node_name, MODE_RWX, 0));
subrata_modakbdbaec52009-02-26 12:14:51 +0000131
plars865695b2001-08-27 22:15:12 +0000132 /* Check return code from mknod(2) */
133 if (TEST_RETURN == -1) {
134 tst_resm(TFAIL,
135 "mknod(%s, %#o, 0) failed, errno=%d : %s",
136 node_name, MODE_RWX, TEST_ERRNO,
137 strerror(TEST_ERRNO));
138 continue;
139 }
140 /*
141 * Perform functional verification if test executed
142 * without (-f) option.
143 */
144 if (STD_FUNCTIONAL_TEST) {
145 /* Set the functionality flag */
146 fflag = 1;
147
148 /* Check for node's creation */
subrata_modak56207ce2009-03-23 13:35:39 +0000149 if (stat(node_name, &buf) < 0) {
plars865695b2001-08-27 22:15:12 +0000150 tst_resm(TFAIL,
151 "stat() of %s failed, errno:%d",
152 node_name, TEST_ERRNO);
153 /* unset flag as functionality fails */
154 fflag = 0;
155 }
156
157 /* Verify mode permissions of node */
158 if (buf.st_mode & S_ISGID) {
159 tst_resm(TFAIL, "%s: Incorrect modes, setgid "
160 "bit set", node_name);
161 /* unset flag as functionality fails */
162 fflag = 0;
163 }
164
165 /* Verify group ID */
166 if (buf.st_gid != mygid) {
167 tst_resm(TFAIL, "%s: Incorrect group",
168 node_name);
169 /* unset flag as functionality fails */
170 fflag = 0;
171 }
172 if (fflag) {
173 tst_resm(TPASS, "Functionality of mknod(%s, "
174 "%#o, 0) successful",
subrata_modak56207ce2009-03-23 13:35:39 +0000175 node_name, MODE_RWX);
plars865695b2001-08-27 22:15:12 +0000176 }
177 } else {
178 tst_resm(TPASS, "call succeeded");
179 }
180
181 /* Remove the node for the next go `round */
182 if (unlink(node_name) == -1) {
subrata_modak56207ce2009-03-23 13:35:39 +0000183 tst_resm(TWARN,
plars865695b2001-08-27 22:15:12 +0000184 "unlink(%s) failed, errno:%d %s",
185 node_name, errno, strerror(errno));
186 }
subrata_modak56207ce2009-03-23 13:35:39 +0000187 }
plars865695b2001-08-27 22:15:12 +0000188
189 /* Change the directory back to temporary directory */
190 chdir("..");
191
192 /*
193 * Invoke cleanup() to delete the test directories created
194 * in the setup() and exit main().
195 */
196 cleanup();
197
subrata_modak56207ce2009-03-23 13:35:39 +0000198 /*NOTREACHED*/ return 0;
199} /* End main */
plars865695b2001-08-27 22:15:12 +0000200
201/*
202 * setup(void) - performs all ONE TIME setup for this test.
subrata_modak56207ce2009-03-23 13:35:39 +0000203 * Exit the test program on receipt of unexpected signals.
plars865695b2001-08-27 22:15:12 +0000204 * Create a temporary directory used to hold test directories created
205 * and change the directory to it.
206 * Verify that pid of process executing the test is root.
207 * Create a test directory on temporary directory and set the ownership
208 * of test directory to nobody user.
209 * Set the effective uid/gid of the process to that of nobody user.
210 */
subrata_modak56207ce2009-03-23 13:35:39 +0000211void setup()
plars865695b2001-08-27 22:15:12 +0000212{
plars865695b2001-08-27 22:15:12 +0000213
214 /* Capture unexpected signals */
215 tst_sig(NOFORK, DEF_HANDLER, cleanup);
216
217 /* Check that the test process id is super/root */
218 if (geteuid() != 0) {
subrata_modak4bb656a2009-02-26 12:02:09 +0000219 tst_brkm(TBROK, NULL, "Must be super/root for this test!");
plars865695b2001-08-27 22:15:12 +0000220 tst_exit();
221 }
222
223 /* Pause if that option was specified */
224 TEST_PAUSE;
225
226 /* Make a temp dir and cd to it */
227 tst_tmpdir();
228
subrata_modak56207ce2009-03-23 13:35:39 +0000229 /* fix permissions on the tmpdir */
230 if (chmod(".", 0711) != 0) {
231 tst_brkm(TBROK, cleanup, "chmod() failed");
232 }
plars05a3b8b2001-09-05 15:37:06 +0000233
plars865695b2001-08-27 22:15:12 +0000234 /* Save the real user id of the test process */
subrata_modak56207ce2009-03-23 13:35:39 +0000235 save_myuid = getuid();
plars865695b2001-08-27 22:15:12 +0000236
237 /* Save the process id of the test process */
subrata_modak56207ce2009-03-23 13:35:39 +0000238 mypid = getpid();
plars865695b2001-08-27 22:15:12 +0000239
240 /* Get the node name to be created in the test */
241 sprintf(node_name, TNODE, mypid);
242
243 /* Get the uid/gid of guest user - nobody */
244 if ((user1 = getpwnam(LTPUSER)) == NULL) {
subrata_modak56207ce2009-03-23 13:35:39 +0000245 tst_brkm(TBROK, cleanup, "%s not in /etc/passwd", LTPUSER);
plars865695b2001-08-27 22:15:12 +0000246 }
247 user1_uid = user1->pw_uid;
248 group1_gid = user1->pw_gid;
249
250 /* Get effective group id of the test process */
subrata_modak56207ce2009-03-23 13:35:39 +0000251 group2_gid = getegid();
plars865695b2001-08-27 22:15:12 +0000252
253 /*
254 * Create a test directory under temporary directory with the
255 * specified mode permissions, with uid/gid set to that of guest
256 * user and the test process.
257 */
258 if (mkdir(DIR_TEMP, MODE_RWX) < 0) {
259 tst_brkm(TBROK, cleanup, "mkdir(2) of %s failed", DIR_TEMP);
260 }
261 if (chown(DIR_TEMP, user1_uid, group2_gid) < 0) {
262 tst_brkm(TBROK, cleanup, "chown(2) of %s failed", DIR_TEMP);
263 }
264
265 /*
266 * Verify that test directory created with expected permission modes
267 * and ownerships.
268 */
269 if (stat(DIR_TEMP, &buf) < 0) {
270 tst_brkm(TBROK, cleanup, "stat(2) of %s failed", DIR_TEMP);
271 }
272
273 /* Verify modes of test directory */
274 if (buf.st_mode & S_ISGID) {
275 tst_brkm(TBROK, cleanup,
276 "%s: Incorrect modes, setgid bit set", DIR_TEMP);
277 }
278
279 /* Verify group ID */
280 if (buf.st_gid != group2_gid) {
281 tst_brkm(TBROK, cleanup, "%s: Incorrect group", DIR_TEMP);
282 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000283
subrata_modak56207ce2009-03-23 13:35:39 +0000284 /*
subrata_modak4bb656a2009-02-26 12:02:09 +0000285 * Set the effective group id and user id of the test process
plars865695b2001-08-27 22:15:12 +0000286 * to that of guest user.
287 */
288 if (setgid(group1_gid) < 0) {
289 tst_brkm(TBROK, cleanup,
290 "Unable to set process gid to that of ltp user");
291 }
292 if (setreuid(-1, user1_uid) < 0) {
293 tst_brkm(TBROK, cleanup,
294 "Unable to set process uid to that of ltp user");
295 }
296
297 /* Save the real group ID of the current process */
298 mygid = getgid();
299
300 /* Change directory to DIR_TEMP */
301 if (chdir(DIR_TEMP) < 0) {
302 tst_brkm(TBROK, cleanup,
303 "Unable to change to %s directory", DIR_TEMP);
304 }
305}
306
307/*
308 * cleanup() - Performs all ONE TIME cleanup for this test at
309 * completion or premature exit.
310 * Print test timing stats and errno log if test executed with options.
311 * Restore the real/effective user id of the process changed during
312 * setup().
313 * Remove temporary directory and sub-directories/files under it
314 * created during setup().
315 * Exit the test program with normal exit code.
316 */
subrata_modak56207ce2009-03-23 13:35:39 +0000317void cleanup()
plars865695b2001-08-27 22:15:12 +0000318{
319 /*
320 * print timing stats if that option was specified.
321 * print errno log if that option was specified.
322 */
323 TEST_CLEANUP;
324
325 /*
326 * Restore the effective uid of the process changed in the
327 * setup().
328 */
329 if (setreuid(-1, save_myuid) < 0) {
330 tst_brkm(TBROK, NULL,
331 "resetting process real/effective uid failed");
332 }
333
334 /* Remove files and temporary directory created */
335 tst_rmdir();
subrata_modak56207ce2009-03-23 13:35:39 +0000336
plars865695b2001-08-27 22:15:12 +0000337 /* exit with return code appropriate for results */
338 tst_exit();
339}