blob: d08cefe7df60d043672329f0abfc9edc11e6a82f [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
zenglg.jyf166fc82013-12-06 19:56:27 +08004 * Author: Wayne Boyer
plars865695b2001-08-27 22:15:12 +00005 *
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
zenglg.jyf166fc82013-12-06 19:56:27 +080017 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000019 */
20
21/*
zenglg.jyf166fc82013-12-06 19:56:27 +080022 * Test that fchmod() fails and sets the proper errno values.
plars865695b2001-08-27 22:15:12 +000023 */
24
vapier5b31d1b2006-08-21 06:46:26 +000025#ifndef _GNU_SOURCE
Cyril Hrubis71189102014-06-30 12:10:07 +020026# define _GNU_SOURCE
vapier5b31d1b2006-08-21 06:46:26 +000027#endif
28
Garrett Cooper5741b472010-12-18 19:36:16 -080029#include <sys/types.h>
30#include <sys/stat.h>
plars865695b2001-08-27 22:15:12 +000031#include <stdio.h>
32#include <stdlib.h>
33#include <unistd.h>
34#include <fcntl.h>
35#include <errno.h>
36#include <string.h>
37#include <signal.h>
robbiew15226cd2002-04-10 16:10:40 +000038#include <unistd.h>
plars865695b2001-08-27 22:15:12 +000039#include <grp.h>
40#include <pwd.h>
zenglg.jy70205442013-12-06 19:57:18 +080041#include <sys/mount.h>
plars865695b2001-08-27 22:15:12 +000042
43#include "test.h"
zenglg.jyf166fc82013-12-06 19:56:27 +080044#include "safe_macros.h"
plars865695b2001-08-27 22:15:12 +000045
zenglg.jyf166fc82013-12-06 19:56:27 +080046static int fd1;
47static int fd2;
zenglg.jy70205442013-12-06 19:57:18 +080048static int fd3;
Cyril Hrubis71189102014-06-30 12:10:07 +020049static const char *device;
zenglg.jy70205442013-12-06 19:57:18 +080050static int mount_flag;
51
zenglg.jyf166fc82013-12-06 19:56:27 +080052static struct test_case_t {
53 char *name;
54 int *fd;
plars865695b2001-08-27 22:15:12 +000055 int mode;
56 int exp_errno;
Garrett Cooper5741b472010-12-18 19:36:16 -080057} test_cases[] = {
zenglg.jyf166fc82013-12-06 19:56:27 +080058 {"EPERM", &fd1, 0644, EPERM},
59 {"EBADF", &fd2, 0644, EBADF},
zenglg.jy70205442013-12-06 19:57:18 +080060 {"EROFS", &fd3, 0644, EROFS},
zenglg.jyf166fc82013-12-06 19:56:27 +080061};
plars865695b2001-08-27 22:15:12 +000062
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020063char *TCID = "fchmod06";
zenglg.jyf166fc82013-12-06 19:56:27 +080064int TST_TOTAL = ARRAY_SIZE(test_cases);
plars865695b2001-08-27 22:15:12 +000065
zenglg.jyf166fc82013-12-06 19:56:27 +080066static void setup(void);
67static void cleanup(void);
plars865695b2001-08-27 22:15:12 +000068
subrata_modak56207ce2009-03-23 13:35:39 +000069int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +000070{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020071 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020072 const char *msg;
Cyril Hrubis89af32a2012-10-24 16:39:11 +020073 int i;
plars865695b2001-08-27 22:15:12 +000074
Cyril Hrubis71189102014-06-30 12:10:07 +020075 msg = parse_opts(ac, av, NULL, NULL);
zenglg.jy70205442013-12-06 19:57:18 +080076 if (msg != NULL)
plars865695b2001-08-27 22:15:12 +000077 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Garrett Cooper2c282152010-12-16 00:55:50 -080078
plars865695b2001-08-27 22:15:12 +000079 setup();
80
plars865695b2001-08-27 22:15:12 +000081 for (lc = 0; TEST_LOOPING(lc); lc++) {
Garrett Cooper2c282152010-12-16 00:55:50 -080082
Caspar Zhangd59a6592013-03-07 14:59:12 +080083 tst_count = 0;
plars865695b2001-08-27 22:15:12 +000084
Garrett Cooper5741b472010-12-18 19:36:16 -080085 for (i = 0; i < TST_TOTAL; i++) {
plars865695b2001-08-27 22:15:12 +000086
zenglg.jyf166fc82013-12-06 19:56:27 +080087 TEST(fchmod(*test_cases[i].fd, test_cases[i].mode));
subrata_modakbdbaec52009-02-26 12:14:51 +000088
plars865695b2001-08-27 22:15:12 +000089 if (TEST_RETURN == -1) {
zenglg.jyf166fc82013-12-06 19:56:27 +080090 if (TEST_ERRNO == test_cases[i].exp_errno) {
Wanlong Gao354ebb42012-12-07 10:10:04 +080091 tst_resm(TPASS | TTERRNO,
zenglg.jyf166fc82013-12-06 19:56:27 +080092 "fchmod: test %s success",
93 test_cases[i].name);
94 } else {
Wanlong Gao354ebb42012-12-07 10:10:04 +080095 tst_resm(TFAIL | TTERRNO,
zenglg.jyf166fc82013-12-06 19:56:27 +080096 "fchmod: test %s FAILED with "
97 "unexpect errno: %d",
98 test_cases[i].name,
99 TEST_ERRNO);
100 }
101 } else {
Garrett Cooper5741b472010-12-18 19:36:16 -0800102 tst_resm(TFAIL,
zenglg.jyf166fc82013-12-06 19:56:27 +0800103 "fchmod: test %s success unexpectly",
104 test_cases[i].name);
105 }
Garrett Cooper2c282152010-12-16 00:55:50 -0800106 }
plars865695b2001-08-27 22:15:12 +0000107
Garrett Cooper2c282152010-12-16 00:55:50 -0800108 }
plars865695b2001-08-27 22:15:12 +0000109
plars865695b2001-08-27 22:15:12 +0000110 cleanup();
Garrett Cooper5741b472010-12-18 19:36:16 -0800111 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800112}
plars865695b2001-08-27 22:15:12 +0000113
zenglg.jyf166fc82013-12-06 19:56:27 +0800114static void setup(void)
plars865695b2001-08-27 22:15:12 +0000115{
Cyril Hrubis71189102014-06-30 12:10:07 +0200116 struct passwd *ltpuser;
117 const char *fs_type;
plars865695b2001-08-27 22:15:12 +0000118
plars865695b2001-08-27 22:15:12 +0000119 tst_sig(FORK, DEF_HANDLER, cleanup);
120
Garrett Cooper5741b472010-12-18 19:36:16 -0800121 tst_require_root(NULL);
subrata_modakbdbaec52009-02-26 12:14:51 +0000122
plars865695b2001-08-27 22:15:12 +0000123 TEST_PAUSE;
124
plars865695b2001-08-27 22:15:12 +0000125 tst_tmpdir();
126
Cyril Hrubis71189102014-06-30 12:10:07 +0200127 fs_type = tst_dev_fs_type();
128 device = tst_acquire_device(cleanup);
129
130 if (!device)
131 tst_brkm(TCONF, cleanup, "Failed to obtain block device");
132
133 tst_mkfs(cleanup, device, fs_type, NULL);
zenglg.jy70205442013-12-06 19:57:18 +0800134
135 SAFE_MKDIR(cleanup, "mntpoint", 0755);
136
Cyril Hrubis71189102014-06-30 12:10:07 +0200137 if (mount(device, "mntpoint", fs_type, 0, NULL) < 0) {
zenglg.jy70205442013-12-06 19:57:18 +0800138 tst_brkm(TBROK | TERRNO, cleanup,
139 "mount device:%s failed", device);
140 }
141 mount_flag = 1;
142
143 /* Create a file in the file system, then remount it as read-only */
144 SAFE_TOUCH(cleanup, "mntpoint/tfile_3", 0644, NULL);
145
Cyril Hrubis71189102014-06-30 12:10:07 +0200146 if (mount(device, "mntpoint", fs_type,
zenglg.jy70205442013-12-06 19:57:18 +0800147 MS_REMOUNT | MS_RDONLY, NULL) < 0) {
148 tst_brkm(TBROK | TERRNO, cleanup,
149 "mount device:%s failed", device);
150 }
zenglg.jy70205442013-12-06 19:57:18 +0800151
152 fd3 = SAFE_OPEN(cleanup, "mntpoint/tfile_3", O_RDONLY);
153
zenglg.jyf166fc82013-12-06 19:56:27 +0800154 fd1 = SAFE_OPEN(cleanup, "tfile_1", O_RDWR | O_CREAT, 0666);
155
156 fd2 = SAFE_OPEN(cleanup, "tfile_2", O_RDWR | O_CREAT, 0666);
157
158 SAFE_CLOSE(cleanup, fd2);
159
160 ltpuser = SAFE_GETPWNAM(cleanup, "nobody");
161
162 SAFE_SETEUID(cleanup, ltpuser->pw_uid);
Garrett Cooper2c282152010-12-16 00:55:50 -0800163}
plars865695b2001-08-27 22:15:12 +0000164
zenglg.jyf166fc82013-12-06 19:56:27 +0800165static void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000166{
Cyril Hrubis71189102014-06-30 12:10:07 +0200167 if (seteuid(0))
168 tst_resm(TWARN | TERRNO, "seteuid(0) failed");
plars865695b2001-08-27 22:15:12 +0000169
Cyril Hrubis71189102014-06-30 12:10:07 +0200170 if (fd1 > 0 && close(fd1))
171 tst_resm(TWARN | TERRNO, "close(fd1) failed");
plars865695b2001-08-27 22:15:12 +0000172
Cyril Hrubis71189102014-06-30 12:10:07 +0200173 if (fd3 > 0 && close(fd3))
174 tst_resm(TWARN | TERRNO, "close(fd1) failed");
zenglg.jy70205442013-12-06 19:57:18 +0800175
Cyril Hrubisc60a2302015-01-29 16:28:24 +0100176 if (mount_flag && tst_umount("mntpoint") < 0) {
zenglg.jy70205442013-12-06 19:57:18 +0800177 tst_brkm(TBROK | TERRNO, NULL,
178 "umount device:%s failed", device);
179 }
180
Cyril Hrubis71189102014-06-30 12:10:07 +0200181 if (device)
182 tst_release_device(NULL, device);
zenglg.jy70205442013-12-06 19:57:18 +0800183
Cyril Hrubis71189102014-06-30 12:10:07 +0200184 tst_rmdir();
zenglg.jy70205442013-12-06 19:57:18 +0800185}