blob: bc47295732306429eafaac33a63c6bedb8fc4701 [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 */
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
subrata_modakcbfac502008-08-19 07:23:42 +000018/* */
19/******************************************************************************/
20/*
21 * NAME
22 * setresuid04.c
23 *
24 * DESCRIPTION
25 * Check if setresuid behaves correctly with file permissions.
26 * The test creates a file as ROOT with permissions 0644, does a setresuid
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 * setresuid04 [-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
44 * Must be run as root.
45 */
46#define _GNU_SOURCE 1
47#include <errno.h>
48#include <sys/types.h>
49#include <sys/stat.h>
50#include <sys/wait.h>
51#include <fcntl.h>
52#include <unistd.h>
53#include "test.h"
subrata_modakcbfac502008-08-19 07:23:42 +000054#include <pwd.h>
Han Pingtian75fb0572014-11-28 16:33:41 +080055#include "compat_16.h"
subrata_modakcbfac502008-08-19 07:23:42 +000056
Han Pingtian75fb0572014-11-28 16:33:41 +080057TCID_DEFINE(setresuid04);
subrata_modakcbfac502008-08-19 07:23:42 +000058int TST_TOTAL = 1;
subrata_modakcbfac502008-08-19 07:23:42 +000059char nobody_uid[] = "nobody";
60char testfile[256] = "";
61struct passwd *ltpuser;
62
subrata_modakcbfac502008-08-19 07:23:42 +000063int fd = -1;
64
65void setup(void);
66void cleanup(void);
67void do_master_child();
68
69int main(int ac, char **av)
70{
71 pid_t pid;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020072 const char *msg;
subrata_modakcbfac502008-08-19 07:23:42 +000073
Garrett Cooper1da938b2011-02-23 21:21:15 -080074 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -080075 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
subrata_modakcbfac502008-08-19 07:23:42 +000076 setup();
77
subrata_modakcbfac502008-08-19 07:23:42 +000078 pid = FORK_OR_VFORK();
79 if (pid < 0)
80 tst_brkm(TBROK, cleanup, "Fork failed");
subrata_modakbdbaec52009-02-26 12:14:51 +000081
Garrett Cooper1da938b2011-02-23 21:21:15 -080082 if (pid == 0)
subrata_modakcbfac502008-08-19 07:23:42 +000083 do_master_child();
Garrett Cooper2c282152010-12-16 00:55:50 -080084
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +030085 tst_record_childstatus(cleanup, pid);
subrata_modakcbfac502008-08-19 07:23:42 +000086
87 cleanup();
Garrett Cooper1e6f5a62010-12-19 09:58:10 -080088 tst_exit();
subrata_modakcbfac502008-08-19 07:23:42 +000089}
90
91/*
92 * do_master_child()
93 */
Mike Frysingerc57fba52014-04-09 18:56:30 -040094void do_master_child(void)
subrata_modakcbfac502008-08-19 07:23:42 +000095{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020096 int lc;
subrata_modakcbfac502008-08-19 07:23:42 +000097 int pid;
98 int status;
99
subrata_modakcbfac502008-08-19 07:23:42 +0000100 for (lc = 0; TEST_LOOPING(lc); lc++) {
101 int tst_fd;
102
Caspar Zhangd59a6592013-03-07 14:59:12 +0800103 /* Reset tst_count in case we are looping */
104 tst_count = 0;
subrata_modakcbfac502008-08-19 07:23:42 +0000105
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +0300106 if (SETRESUID(NULL, 0, ltpuser->pw_uid, 0) == -1) {
Han Pingtian75fb0572014-11-28 16:33:41 +0800107 perror("setresuid failed");
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +0300108 exit(TFAIL);
subrata_modakcbfac502008-08-19 07:23:42 +0000109 }
110
111 /* Test 1: Check the process with new uid cannot open the file
112 * with RDWR permissions.
113 */
114 TEST(tst_fd = open(testfile, O_RDWR));
115
116 if (TEST_RETURN != -1) {
Garrett Cooper1da938b2011-02-23 21:21:15 -0800117 printf("open succeeded unexpectedly\n");
subrata_modakcbfac502008-08-19 07:23:42 +0000118 close(tst_fd);
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +0300119 exit(TFAIL);
subrata_modakcbfac502008-08-19 07:23:42 +0000120 }
121
122 if (TEST_ERRNO == EACCES) {
Garrett Cooper1da938b2011-02-23 21:21:15 -0800123 printf("open failed with EACCES as expected\n");
subrata_modakcbfac502008-08-19 07:23:42 +0000124 } else {
Garrett Cooper1da938b2011-02-23 21:21:15 -0800125 perror("open failed unexpectedly");
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +0300126 exit(TFAIL);
subrata_modakcbfac502008-08-19 07:23:42 +0000127 }
128
129 /* Test 2: Check a son process cannot open the file
130 * with RDWR permissions.
131 */
132 pid = FORK_OR_VFORK();
133 if (pid < 0)
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +0300134 tst_brkm(TBROK, NULL, "Fork failed");
subrata_modakcbfac502008-08-19 07:23:42 +0000135
136 if (pid == 0) {
subrata_modak4bb656a2009-02-26 12:02:09 +0000137 int tst_fd2;
subrata_modakcbfac502008-08-19 07:23:42 +0000138
139 /* Test to open the file in son process */
140 TEST(tst_fd2 = open(testfile, O_RDWR));
141
142 if (TEST_RETURN != -1) {
Garrett Cooper1da938b2011-02-23 21:21:15 -0800143 printf("call succeeded unexpectedly\n");
subrata_modakcbfac502008-08-19 07:23:42 +0000144 close(tst_fd2);
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +0300145 exit(TFAIL);
subrata_modakcbfac502008-08-19 07:23:42 +0000146 }
147
subrata_modakcbfac502008-08-19 07:23:42 +0000148 if (TEST_ERRNO == EACCES) {
Garrett Cooper1da938b2011-02-23 21:21:15 -0800149 printf("open failed with EACCES as expected\n");
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +0300150 exit(TPASS);
subrata_modakcbfac502008-08-19 07:23:42 +0000151 } else {
Garrett Cooper1da938b2011-02-23 21:21:15 -0800152 printf("open failed unexpectedly\n");
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +0300153 exit(TFAIL);
subrata_modakcbfac502008-08-19 07:23:42 +0000154 }
subrata_modak56207ce2009-03-23 13:35:39 +0000155 } else {
subrata_modakcbfac502008-08-19 07:23:42 +0000156 /* Wait for son completion */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800157 if (waitpid(pid, &status, 0) == -1) {
Garrett Cooper1da938b2011-02-23 21:21:15 -0800158 perror("waitpid failed");
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +0300159 exit(TFAIL);
Garrett Cooper1da938b2011-02-23 21:21:15 -0800160 }
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +0300161
162 if (!WIFEXITED(status))
163 exit(TFAIL);
164
165 if (WEXITSTATUS(status) != TPASS)
subrata_modakcbfac502008-08-19 07:23:42 +0000166 exit(WEXITSTATUS(status));
167 }
168
169 /* Test 3: Fallback to initial uid and check we can again open
170 * the file with RDWR permissions.
171 */
Caspar Zhangd59a6592013-03-07 14:59:12 +0800172 tst_count++;
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +0300173 if (SETRESUID(NULL, 0, 0, 0) == -1) {
Han Pingtian75fb0572014-11-28 16:33:41 +0800174 perror("setresuid failed");
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +0300175 exit(TFAIL);
subrata_modakcbfac502008-08-19 07:23:42 +0000176 }
177
178 TEST(tst_fd = open(testfile, O_RDWR));
179
180 if (TEST_RETURN == -1) {
Garrett Cooper1da938b2011-02-23 21:21:15 -0800181 perror("open failed unexpectedly");
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +0300182 exit(TFAIL);
subrata_modak56207ce2009-03-23 13:35:39 +0000183 } else {
Garrett Cooper1da938b2011-02-23 21:21:15 -0800184 printf("open call succeeded\n");
subrata_modak56207ce2009-03-23 13:35:39 +0000185 close(tst_fd);
subrata_modakcbfac502008-08-19 07:23:42 +0000186 }
187 }
Stanislav Kholmanskikh0a451532014-11-28 17:36:21 +0300188 exit(TPASS);
subrata_modakcbfac502008-08-19 07:23:42 +0000189}
190
191/*
192 * setup() - performs all ONE TIME setup for this test
193 */
subrata_modak56207ce2009-03-23 13:35:39 +0000194void setup(void)
subrata_modakcbfac502008-08-19 07:23:42 +0000195{
Garrett Cooper1da938b2011-02-23 21:21:15 -0800196 tst_require_root(NULL);
subrata_modakcbfac502008-08-19 07:23:42 +0000197
subrata_modakbdbaec52009-02-26 12:14:51 +0000198 ltpuser = getpwnam(nobody_uid);
subrata_modakcbfac502008-08-19 07:23:42 +0000199
Han Pingtian75fb0572014-11-28 16:33:41 +0800200 UID16_CHECK(ltpuser->pw_uid, "setresuid", cleanup)
201
subrata_modak9e89d9a2008-09-08 08:52:52 +0000202 tst_tmpdir();
203
subrata_modakcbfac502008-08-19 07:23:42 +0000204 sprintf(testfile, "setresuid04file%d.tst", getpid());
205
206 /* Create test file */
207 fd = open(testfile, O_CREAT | O_RDWR, 0644);
208 if (fd < 0)
209 tst_brkm(TBROK, cleanup, "cannot creat test file");
210
subrata_modakcbfac502008-08-19 07:23:42 +0000211 tst_sig(FORK, DEF_HANDLER, cleanup);
212
subrata_modakcbfac502008-08-19 07:23:42 +0000213 TEST_PAUSE;
214}
215
216/*
217 * cleanup() - performs all the ONE TIME cleanup for this test at completion
218 * or premature exit
219 */
subrata_modak56207ce2009-03-23 13:35:39 +0000220void cleanup(void)
subrata_modakcbfac502008-08-19 07:23:42 +0000221{
subrata_modak56207ce2009-03-23 13:35:39 +0000222 close(fd);
subrata_modakcbfac502008-08-19 07:23:42 +0000223
subrata_modak9e89d9a2008-09-08 08:52:52 +0000224 tst_rmdir();
225
Garrett Cooper1da938b2011-02-23 21:21:15 -0800226}