blob: c97248cdb89a477d62701f9fa560ee8847da2f27 [file] [log] [blame]
subrata_modakcbfac502008-08-19 07:23:42 +00001/******************************************************************************/
2/* Copyright (c) Kerlabs 2008. */
3/* Copyright (c) International Business Machines Corp., 2008 */
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
subrata_modak56207ce2009-03-23 13:35:39 +000022 * setreuid07.c
subrata_modakcbfac502008-08-19 07:23:42 +000023 *
24 * DESCRIPTION
subrata_modak56207ce2009-03-23 13:35:39 +000025 * Check if setreuid behaves correctly with file permissions.
subrata_modakcbfac502008-08-19 07:23:42 +000026 * The test creates a file as ROOT with permissions 0644, does a setreuid
27 * and then tries to open the file with RDWR permissions.
28 * The same test is done in a fork to check if new UIDs are correctly
29 * passed to the son.
30 *
31 * USAGE: <for command-line>
32 * setreuid07 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
33 * where, -c n : Run n copies concurrently.
34 * -e : Turn on errno logging.
35 * -i n : Execute test n times.
36 * -I x : Execute test for x seconds.
37 * -P x : Pause for x seconds between iterations.
38 * -t : Turn on syscall timing.
39 *
40 * HISTORY
41 * 07/2001 Created by Renaud Lottiaux
42 *
43 * RESTRICTIONS
subrata_modak56207ce2009-03-23 13:35:39 +000044 * Must be run as root.
subrata_modakcbfac502008-08-19 07:23:42 +000045 */
46#include <errno.h>
47#include <sys/types.h>
48#include <sys/stat.h>
49#include <sys/wait.h>
50#include <fcntl.h>
51#include <unistd.h>
52#include "test.h"
53#include "usctest.h"
54#include <pwd.h>
55
56char *TCID = "setreuid07";
57int TST_TOTAL = 1;
58extern int Tst_count;
59char nobody_uid[] = "nobody";
60char testfile[256] = "";
61struct passwd *ltpuser;
62
subrata_modak56207ce2009-03-23 13:35:39 +000063int exp_enos[] = { EACCES, 0 };
subrata_modakcbfac502008-08-19 07:23:42 +000064int fd = -1;
65
66void setup(void);
67void cleanup(void);
68void do_master_child();
69
70int main(int ac, char **av)
71{
72 pid_t pid;
subrata_modak56207ce2009-03-23 13:35:39 +000073 char *msg; /* message returned from parse_opts */
subrata_modakcbfac502008-08-19 07:23:42 +000074 int status;
75
76 /* parse standard options */
Garrett Coopere1f008e2010-12-14 00:21:59 -080077 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
subrata_modakcbfac502008-08-19 07:23:42 +000078 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
subrata_modak56207ce2009-03-23 13:35:39 +000079 /*NOTREACHED*/}
subrata_modakcbfac502008-08-19 07:23:42 +000080
81 /*
82 * perform global setup for the test
83 */
84 setup();
85
86 TEST_EXP_ENOS(exp_enos);
87
88 pid = FORK_OR_VFORK();
89 if (pid < 0)
90 tst_brkm(TBROK, cleanup, "Fork failed");
subrata_modakbdbaec52009-02-26 12:14:51 +000091
subrata_modakcbfac502008-08-19 07:23:42 +000092 if (pid == 0) {
93 do_master_child();
subrata_modak9e89d9a2008-09-08 08:52:52 +000094 return 0;
subrata_modak56207ce2009-03-23 13:35:39 +000095 } else {
subrata_modakcbfac502008-08-19 07:23:42 +000096 waitpid(pid, &status, 0);
97 if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
subrata_modak56207ce2009-03-23 13:35:39 +000098 tst_resm(WEXITSTATUS(status),
99 "son process exits with error");
subrata_modakcbfac502008-08-19 07:23:42 +0000100 }
101
102 cleanup();
subrata_modak56207ce2009-03-23 13:35:39 +0000103 /*NOTREACHED*/ return 0;
subrata_modakcbfac502008-08-19 07:23:42 +0000104}
105
106/*
107 * do_master_child()
108 */
109void do_master_child()
110{
subrata_modak56207ce2009-03-23 13:35:39 +0000111 int lc; /* loop counter */
subrata_modakcbfac502008-08-19 07:23:42 +0000112 int pid;
113 int status;
114
115 /* Check looping state if -i option is given */
116 for (lc = 0; TEST_LOOPING(lc); lc++) {
117 int tst_fd;
118
119 /* Reset Tst_count in case we are looping */
120 Tst_count = 0;
121
122 if (setreuid(0, ltpuser->pw_uid) == -1) {
subrata_modak4bb656a2009-02-26 12:02:09 +0000123 tst_brkm(TBROK, cleanup,
subrata_modakcbfac502008-08-19 07:23:42 +0000124 "setreuid failed to set the euid to %d",
125 ltpuser->pw_uid);
126 }
127
128 /* Test 1: Check the process with new uid cannot open the file
129 * with RDWR permissions.
130 */
131 TEST(tst_fd = open(testfile, O_RDWR));
132
133 if (TEST_RETURN != -1) {
134 tst_resm(TFAIL, "call succeeded unexpectedly");
135 close(tst_fd);
136 }
137
138 if (TEST_ERRNO == EACCES) {
139 tst_resm(TPASS, "open returned errno EACCES");
140 } else {
141 tst_resm(TFAIL, "open returned unexpected errno - %d",
142 TEST_ERRNO);
143 continue;
144 }
145
146 /* Test 2: Check a son process cannot open the file
147 * with RDWR permissions.
148 */
149 pid = FORK_OR_VFORK();
150 if (pid < 0)
151 tst_brkm(TBROK, cleanup, "Fork failed");
152
153 if (pid == 0) {
subrata_modak4bb656a2009-02-26 12:02:09 +0000154 int tst_fd2;
subrata_modakcbfac502008-08-19 07:23:42 +0000155
156 /* Test to open the file in son process */
157 TEST(tst_fd2 = open(testfile, O_RDWR));
158
159 if (TEST_RETURN != -1) {
160 tst_resm(TFAIL, "call succeeded unexpectedly");
161 close(tst_fd2);
162 }
163
164 TEST_ERROR_LOG(TEST_ERRNO);
subrata_modak56207ce2009-03-23 13:35:39 +0000165
subrata_modakcbfac502008-08-19 07:23:42 +0000166 if (TEST_ERRNO == EACCES) {
167 tst_resm(TPASS, "open returned errno EACCES");
168 } else {
subrata_modak56207ce2009-03-23 13:35:39 +0000169 tst_resm(TFAIL,
170 "open returned unexpected errno - %d",
subrata_modakcbfac502008-08-19 07:23:42 +0000171 TEST_ERRNO);
172 }
173 continue;
subrata_modak56207ce2009-03-23 13:35:39 +0000174 } else {
subrata_modakcbfac502008-08-19 07:23:42 +0000175 /* Wait for son completion */
176 waitpid(pid, &status, 0);
177 if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
178 exit(WEXITSTATUS(status));
179 }
180
181 /* Test 3: Fallback to initial uid and check we can again open
182 * the file with RDWR permissions.
183 */
184 Tst_count++;
185 if (setreuid(0, 0) == -1) {
subrata_modak4bb656a2009-02-26 12:02:09 +0000186 tst_brkm(TBROK, cleanup,
subrata_modakcbfac502008-08-19 07:23:42 +0000187 "setreuid failed to set the euid to 0");
188 }
189
190 TEST(tst_fd = open(testfile, O_RDWR));
191
192 if (TEST_RETURN == -1) {
193 tst_resm(TFAIL, "open returned unexpected errno %d",
194 TEST_ERRNO);
195 continue;
subrata_modak56207ce2009-03-23 13:35:39 +0000196 } else {
subrata_modakcbfac502008-08-19 07:23:42 +0000197 tst_resm(TPASS, "open call succeeded");
subrata_modak56207ce2009-03-23 13:35:39 +0000198 close(tst_fd);
subrata_modakcbfac502008-08-19 07:23:42 +0000199 }
200 }
201}
202
203/*
204 * setup() - performs all ONE TIME setup for this test
205 */
subrata_modak56207ce2009-03-23 13:35:39 +0000206void setup(void)
subrata_modakcbfac502008-08-19 07:23:42 +0000207{
subrata_modak56207ce2009-03-23 13:35:39 +0000208 if (geteuid() != 0) {
209 tst_brkm(TBROK, tst_exit, "Test must be run as root");
210 }
subrata_modakcbfac502008-08-19 07:23:42 +0000211
subrata_modakbdbaec52009-02-26 12:14:51 +0000212 ltpuser = getpwnam(nobody_uid);
subrata_modakcbfac502008-08-19 07:23:42 +0000213
subrata_modak9e89d9a2008-09-08 08:52:52 +0000214 /* make a temp directory and cd to it */
215 tst_tmpdir();
216
subrata_modakcbfac502008-08-19 07:23:42 +0000217 sprintf(testfile, "setreuid07file%d.tst", getpid());
218
219 /* Create test file */
220 fd = open(testfile, O_CREAT | O_RDWR, 0644);
221 if (fd < 0)
222 tst_brkm(TBROK, cleanup, "cannot creat test file");
223
224 /* capture signals */
225 tst_sig(FORK, DEF_HANDLER, cleanup);
226
227 /* Pause if that option was specified */
228 TEST_PAUSE;
229}
230
231/*
232 * cleanup() - performs all the ONE TIME cleanup for this test at completion
subrata_modak56207ce2009-03-23 13:35:39 +0000233 * or premature exit
subrata_modakcbfac502008-08-19 07:23:42 +0000234 */
subrata_modak56207ce2009-03-23 13:35:39 +0000235void cleanup(void)
subrata_modakcbfac502008-08-19 07:23:42 +0000236{
subrata_modak56207ce2009-03-23 13:35:39 +0000237 close(fd);
subrata_modakcbfac502008-08-19 07:23:42 +0000238
239 /*
240 * print timing status if that option was specified
241 * print errno log if that option was specified
242 */
243 TEST_CLEANUP;
244
subrata_modak9e89d9a2008-09-08 08:52:52 +0000245 /* Remove tmp dir and all files in it */
246 tst_rmdir();
247
subrata_modakcbfac502008-08-19 07:23:42 +0000248 /* exit with return code appropriate for results */
249 tst_exit();
250}