blob: 1ad254aa7bfc29c3bdabe544ac0354163bf33f54 [file] [log] [blame]
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +04001/*****************************************************************************
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/*
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +040022 * Check if setfsuid behaves correctly with file permissions.
23 * The test creates a file as ROOT with permissions 0644, does a setfsuid
24 * and then tries to open the file with RDWR permissions.
25 * The same test is done in a fork to check if new UIDs are correctly
26 * passed to the son.
subrata_modakcbfac502008-08-19 07:23:42 +000027 */
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +040028
subrata_modakcbfac502008-08-19 07:23:42 +000029#include <sys/types.h>
Garrett Cooper72dd5a72011-02-15 23:02:07 -080030#include <sys/stat.h>
31#include <sys/wait.h>
32#include <errno.h>
33#include <fcntl.h>
34#include <pwd.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <unistd.h>
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +040039
subrata_modakcbfac502008-08-19 07:23:42 +000040#include "test.h"
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +040041#include "compat_16.h"
subrata_modakcbfac502008-08-19 07:23:42 +000042
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +040043TCID_DEFINE(setfsuid04);
subrata_modakcbfac502008-08-19 07:23:42 +000044int TST_TOTAL = 1;
subrata_modakcbfac502008-08-19 07:23:42 +000045
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +040046static char nobody_uid[] = "nobody";
47static char testfile[] = "setfsuid04_testfile";
48static struct passwd *ltpuser;
Wanlong Gao354ebb42012-12-07 10:10:04 +080049
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +040050static int fd = -1;
subrata_modakcbfac502008-08-19 07:23:42 +000051
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +040052static void setup(void);
53static void cleanup(void);
54static void do_master_child(void);
subrata_modakcbfac502008-08-19 07:23:42 +000055
56int main(int ac, char **av)
57{
58 pid_t pid;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020059 const char *msg;
subrata_modakcbfac502008-08-19 07:23:42 +000060
Garrett Cooper72dd5a72011-02-15 23:02:07 -080061 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -080062 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
subrata_modakcbfac502008-08-19 07:23:42 +000063
subrata_modakcbfac502008-08-19 07:23:42 +000064 setup();
65
subrata_modakcbfac502008-08-19 07:23:42 +000066 pid = FORK_OR_VFORK();
67 if (pid < 0)
68 tst_brkm(TBROK, cleanup, "Fork failed");
subrata_modakbdbaec52009-02-26 12:14:51 +000069
Garrett Cooper72dd5a72011-02-15 23:02:07 -080070 if (pid == 0)
subrata_modakcbfac502008-08-19 07:23:42 +000071 do_master_child();
Garrett Cooper2c282152010-12-16 00:55:50 -080072
Xiaoguang Wangd84d9012014-07-28 19:51:41 +080073 tst_record_childstatus(cleanup, pid);
subrata_modakcbfac502008-08-19 07:23:42 +000074
75 cleanup();
Garrett Cooper1e6f5a62010-12-19 09:58:10 -080076 tst_exit();
subrata_modakcbfac502008-08-19 07:23:42 +000077}
78
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +040079static void do_master_child(void)
subrata_modakcbfac502008-08-19 07:23:42 +000080{
subrata_modakcbfac502008-08-19 07:23:42 +000081 int pid;
82 int status;
83
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +040084 if (SETFSUID(NULL, ltpuser->pw_uid) == -1) {
Garrett Cooper72dd5a72011-02-15 23:02:07 -080085 perror("setfsuid failed");
Xiaoguang Wangd84d9012014-07-28 19:51:41 +080086 exit(TFAIL);
subrata_modakcbfac502008-08-19 07:23:42 +000087 }
Garrett Cooper72dd5a72011-02-15 23:02:07 -080088
89 /* Test 1: Check the process with new uid cannot open the file
90 * with RDWR permissions.
91 */
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +040092 TEST(open(testfile, O_RDWR));
Garrett Cooper72dd5a72011-02-15 23:02:07 -080093
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +040094 if (TEST_RETURN != -1) {
95 close(TEST_RETURN);
96 printf("open succeeded unexpectedly\n");
Xiaoguang Wangd84d9012014-07-28 19:51:41 +080097 exit(TFAIL);
Garrett Cooper72dd5a72011-02-15 23:02:07 -080098 }
99
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +0400100 if (TEST_ERRNO == EACCES) {
101 printf("open failed with EACCESS as expected\n");
102 } else {
103 printf("open returned unexpected errno - %d\n", TEST_ERRNO);
Xiaoguang Wangd84d9012014-07-28 19:51:41 +0800104 exit(TFAIL);
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800105 }
106
107 /* Test 2: Check a son process cannot open the file
108 * with RDWR permissions.
109 */
110 pid = FORK_OR_VFORK();
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +0400111 if (pid < 0) {
112 perror("Fork failed");
Xiaoguang Wangd84d9012014-07-28 19:51:41 +0800113 exit(TFAIL);
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +0400114 }
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800115
116 if (pid == 0) {
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800117 /* Test to open the file in son process */
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +0400118 TEST(open(testfile, O_RDWR));
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800119
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +0400120 if (TEST_RETURN != -1) {
121 close(TEST_RETURN);
122 printf("open succeeded unexpectedly\n");
Xiaoguang Wangd84d9012014-07-28 19:51:41 +0800123 exit(TFAIL);
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800124 }
125
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +0400126 if (TEST_ERRNO == EACCES) {
127 printf("open failed with EACCESS as expected\n");
128 } else {
129 printf("open returned unexpected errno - %d\n",
130 TEST_ERRNO);
Xiaoguang Wangd84d9012014-07-28 19:51:41 +0800131 exit(TFAIL);
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800132 }
133 } else {
134 /* Wait for son completion */
135 if (waitpid(pid, &status, 0) == -1) {
136 perror("waitpid failed");
Xiaoguang Wangd84d9012014-07-28 19:51:41 +0800137 exit(TFAIL);
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800138 }
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +0400139
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800140 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
141 exit(WEXITSTATUS(status));
142 }
143
144 /* Test 3: Fallback to initial uid and check we can again open
145 * the file with RDWR permissions.
146 */
Caspar Zhangd59a6592013-03-07 14:59:12 +0800147 tst_count++;
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +0400148 if (SETFSUID(NULL, 0) == -1) {
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800149 perror("setfsuid failed");
Xiaoguang Wangd84d9012014-07-28 19:51:41 +0800150 exit(TFAIL);
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800151 }
152
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +0400153 TEST(open(testfile, O_RDWR));
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800154
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +0400155 if (TEST_RETURN == -1) {
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800156 perror("open failed unexpectedly");
Xiaoguang Wangd84d9012014-07-28 19:51:41 +0800157 exit(TFAIL);
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800158 } else {
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +0400159 printf("open call succeeded\n");
160 close(TEST_RETURN);
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800161 }
Xiaoguang Wangd84d9012014-07-28 19:51:41 +0800162 exit(TPASS);
subrata_modakcbfac502008-08-19 07:23:42 +0000163}
164
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +0400165static void setup(void)
subrata_modakcbfac502008-08-19 07:23:42 +0000166{
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800167 tst_require_root(NULL);
subrata_modakcbfac502008-08-19 07:23:42 +0000168
subrata_modakbdbaec52009-02-26 12:14:51 +0000169 ltpuser = getpwnam(nobody_uid);
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +0400170 if (ltpuser == NULL)
171 tst_brkm(TBROK, cleanup, "getpwnam failed for user id %s",
172 nobody_uid);
173
174 UID16_CHECK(ltpuser->pw_uid, setfsuid, cleanup);
subrata_modakcbfac502008-08-19 07:23:42 +0000175
subrata_modak9e89d9a2008-09-08 08:52:52 +0000176 tst_tmpdir();
177
subrata_modakcbfac502008-08-19 07:23:42 +0000178 /* Create test file */
179 fd = open(testfile, O_CREAT | O_RDWR, 0644);
180 if (fd < 0)
181 tst_brkm(TBROK, cleanup, "cannot creat test file");
182
subrata_modakcbfac502008-08-19 07:23:42 +0000183 tst_sig(FORK, DEF_HANDLER, cleanup);
184
subrata_modakcbfac502008-08-19 07:23:42 +0000185 TEST_PAUSE;
186}
187
Stanislav Kholmanskikh0e7a99b2013-09-13 13:59:10 +0400188static void cleanup(void)
subrata_modakcbfac502008-08-19 07:23:42 +0000189{
subrata_modak56207ce2009-03-23 13:35:39 +0000190 close(fd);
subrata_modak9e89d9a2008-09-08 08:52:52 +0000191 tst_rmdir();
Garrett Cooper72dd5a72011-02-15 23:02:07 -0800192}