blob: 27277a08997ae6ff8d65df79d1e979e892c7bdbd [file] [log] [blame]
Cyril Hrubis7dc42c92013-09-12 14:55:55 +02001/******************************************************************************
2 * Copyright (c) Kerlabs 2008. *
3 * Copyright (c) International Business Machines Corp., 2008 *
4 * Created by Renaud Lottiaux *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See *
14 * the GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software Foundation, *
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
19 *****************************************************************************/
20
subrata_modakcbfac502008-08-19 07:23:42 +000021/*
Cyril Hrubis7dc42c92013-09-12 14:55:55 +020022 * Check if setuid behaves correctly with file permissions. The test creates a
23 * file as ROOT with permissions 0644, does a setuid and then tries to open the
24 * file with RDWR permissions. The same test is done in a fork to check if new
25 * UIDs are correctly passed to the son.
subrata_modakcbfac502008-08-19 07:23:42 +000026 */
Cyril Hrubis7dc42c92013-09-12 14:55:55 +020027
subrata_modakcbfac502008-08-19 07:23:42 +000028#include <errno.h>
Stanislav Kholmanskikh1c442442013-09-11 13:25:43 +040029#include <pwd.h>
subrata_modakcbfac502008-08-19 07:23:42 +000030#include <sys/types.h>
31#include <sys/stat.h>
32#include <sys/wait.h>
33#include <fcntl.h>
34#include <unistd.h>
Stanislav Kholmanskikh1c442442013-09-11 13:25:43 +040035
subrata_modakcbfac502008-08-19 07:23:42 +000036#include "test.h"
Stanislav Kholmanskikh1c442442013-09-11 13:25:43 +040037#include "compat_16.h"
subrata_modakcbfac502008-08-19 07:23:42 +000038
39char *TCID = "setuid04";
40int TST_TOTAL = 1;
subrata_modakcbfac502008-08-19 07:23:42 +000041
Cyril Hrubis7dc42c92013-09-12 14:55:55 +020042static char nobody_uid[] = "nobody";
Cyril Hrubis38753442013-09-12 14:58:41 +020043static char testfile[] = "setuid04_testfile";
Cyril Hrubis7dc42c92013-09-12 14:55:55 +020044static struct passwd *ltpuser;
Wanlong Gao354ebb42012-12-07 10:10:04 +080045
Cyril Hrubis7dc42c92013-09-12 14:55:55 +020046static int fd = -1;
47
48static void setup(void);
49static void cleanup(void);
50static void do_master_child(void);
subrata_modakcbfac502008-08-19 07:23:42 +000051
52int main(int ac, char **av)
53{
54 pid_t pid;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020055 const char *msg;
subrata_modakcbfac502008-08-19 07:23:42 +000056 int status;
57
Cyril Hrubis7dc42c92013-09-12 14:55:55 +020058 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -080059 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
subrata_modakcbfac502008-08-19 07:23:42 +000060
subrata_modakcbfac502008-08-19 07:23:42 +000061 setup();
62
subrata_modakcbfac502008-08-19 07:23:42 +000063 pid = FORK_OR_VFORK();
64 if (pid < 0)
65 tst_brkm(TBROK, cleanup, "Fork failed");
subrata_modakbdbaec52009-02-26 12:14:51 +000066
subrata_modakcbfac502008-08-19 07:23:42 +000067 if (pid == 0) {
68 do_master_child();
subrata_modak56207ce2009-03-23 13:35:39 +000069 } else {
subrata_modakcbfac502008-08-19 07:23:42 +000070 waitpid(pid, &status, 0);
71 if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
subrata_modak56207ce2009-03-23 13:35:39 +000072 tst_resm(WEXITSTATUS(status),
73 "son process exits with error");
subrata_modakcbfac502008-08-19 07:23:42 +000074 }
75
76 cleanup();
Garrett Cooper1e6f5a62010-12-19 09:58:10 -080077 tst_exit();
subrata_modakcbfac502008-08-19 07:23:42 +000078}
79
Cyril Hrubis7dc42c92013-09-12 14:55:55 +020080static void do_master_child(void)
subrata_modakcbfac502008-08-19 07:23:42 +000081{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020082 int lc;
subrata_modakcbfac502008-08-19 07:23:42 +000083 int pid;
84 int status;
85
MaShimiao7f5bfb82013-09-26 17:42:02 +080086 if (SETUID(NULL, ltpuser->pw_uid) == -1) {
Garrett Cooper53740502010-12-16 00:04:01 -080087 tst_brkm(TBROK, NULL,
subrata_modakcbfac502008-08-19 07:23:42 +000088 "setuid failed to set the effective uid to %d",
89 ltpuser->pw_uid);
90 }
91
subrata_modakcbfac502008-08-19 07:23:42 +000092 for (lc = 0; TEST_LOOPING(lc); lc++) {
93 int tst_fd;
94
Caspar Zhangd59a6592013-03-07 14:59:12 +080095 tst_count = 0;
subrata_modakcbfac502008-08-19 07:23:42 +000096
97 TEST(tst_fd = open(testfile, O_RDWR));
98
99 if (TEST_RETURN != -1) {
100 tst_resm(TFAIL, "call succeeded unexpectedly");
101 close(tst_fd);
102 }
103
104 if (TEST_ERRNO == EACCES) {
105 tst_resm(TPASS, "open returned errno EACCES");
106 } else {
107 tst_resm(TFAIL, "open returned unexpected errno - %d",
108 TEST_ERRNO);
109 continue;
110 }
111
112 pid = FORK_OR_VFORK();
113 if (pid < 0)
Garrett Cooper53740502010-12-16 00:04:01 -0800114 tst_brkm(TBROK, NULL, "Fork failed");
subrata_modakcbfac502008-08-19 07:23:42 +0000115
116 if (pid == 0) {
subrata_modak4bb656a2009-02-26 12:02:09 +0000117 int tst_fd2;
subrata_modakcbfac502008-08-19 07:23:42 +0000118
119 /* Test to open the file in son process */
120 TEST(tst_fd2 = open(testfile, O_RDWR));
121
122 if (TEST_RETURN != -1) {
123 tst_resm(TFAIL, "call succeeded unexpectedly");
124 close(tst_fd2);
125 }
126
subrata_modakcbfac502008-08-19 07:23:42 +0000127 if (TEST_ERRNO == EACCES) {
128 tst_resm(TPASS, "open returned errno EACCES");
129 } else {
subrata_modak56207ce2009-03-23 13:35:39 +0000130 tst_resm(TFAIL,
131 "open returned unexpected errno - %d",
subrata_modakcbfac502008-08-19 07:23:42 +0000132 TEST_ERRNO);
subrata_modakcbfac502008-08-19 07:23:42 +0000133 }
subrata_modakc8915972009-06-23 14:07:59 +0000134 tst_exit();
subrata_modak56207ce2009-03-23 13:35:39 +0000135 } else {
subrata_modakcbfac502008-08-19 07:23:42 +0000136 /* Wait for son completion */
137 waitpid(pid, &status, 0);
138 if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
139 exit(WEXITSTATUS(status));
140 }
141 }
subrata_modak80e41942009-06-25 08:16:54 +0000142 tst_exit();
subrata_modakcbfac502008-08-19 07:23:42 +0000143}
144
Cyril Hrubis7dc42c92013-09-12 14:55:55 +0200145static void setup(void)
subrata_modakcbfac502008-08-19 07:23:42 +0000146{
Stanislav Kholmanskikh1c442442013-09-11 13:25:43 +0400147 tst_require_root(NULL);
subrata_modakcbfac502008-08-19 07:23:42 +0000148
subrata_modakbdbaec52009-02-26 12:14:51 +0000149 ltpuser = getpwnam(nobody_uid);
subrata_modakcbfac502008-08-19 07:23:42 +0000150
Stanislav Kholmanskikh1c442442013-09-11 13:25:43 +0400151 if (ltpuser == NULL)
152 tst_brkm(TBROK, cleanup, "getpwnam failed for user id %s",
153 nobody_uid);
154
155 UID16_CHECK(ltpuser->pw_uid, setuid, cleanup);
156
Cyril Hrubis38753442013-09-12 14:58:41 +0200157 tst_tmpdir();
subrata_modakcbfac502008-08-19 07:23:42 +0000158
159 /* Create test file */
160 fd = open(testfile, O_CREAT | O_RDWR, 0644);
161 if (fd < 0)
162 tst_brkm(TBROK, cleanup, "cannot creat test file");
163
subrata_modakcbfac502008-08-19 07:23:42 +0000164 tst_sig(FORK, DEF_HANDLER, cleanup);
165
subrata_modakcbfac502008-08-19 07:23:42 +0000166 TEST_PAUSE;
167}
168
Cyril Hrubis7dc42c92013-09-12 14:55:55 +0200169static void cleanup(void)
subrata_modakcbfac502008-08-19 07:23:42 +0000170{
subrata_modak56207ce2009-03-23 13:35:39 +0000171 close(fd);
Cyril Hrubis38753442013-09-12 14:58:41 +0200172 tst_rmdir();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700173}