blob: 07c4b833334956ccb773317fd5294facf6cecfcf [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
Cyril Hrubis75b30b62014-06-19 16:22:27 +02002 * Copyright (c) International Business Machines Corp., 2001
3 * 07/2001 Ported by Wayne Boyer
4 * Copyright (c) 2014 Cyril Hrubis <chrubis@suse.cz>
plars865695b2001-08-27 22:15:12 +00005 *
Cyril Hrubis75b30b62014-06-19 16:22:27 +02006 * 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.
plars865695b2001-08-27 22:15:12 +000010 *
Cyril Hrubis75b30b62014-06-19 16:22:27 +020011 * 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.
plars865695b2001-08-27 22:15:12 +000015 *
Cyril Hrubis75b30b62014-06-19 16:22:27 +020016 * 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
plars865695b2001-08-27 22:15:12 +000019 */
20
21/*
22 * Test Name: chown04
23 *
24 * Test Description:
25 * Verify that,
26 * 1) chown(2) returns -1 and sets errno to EPERM if the effective user id
subrata_modak945234b2009-04-25 17:52:44 +000027 * of process does not match the owner of the file and the process
28 * is not super user.
plars865695b2001-08-27 22:15:12 +000029 * 2) chown(2) returns -1 and sets errno to EACCES if search permission is
robbiew35e49062002-08-26 14:30:59 +000030 * denied on a component of the path prefix.
plars865695b2001-08-27 22:15:12 +000031 * 3) chown(2) returns -1 and sets errno to EFAULT if pathname points
robbiew35e49062002-08-26 14:30:59 +000032 * outside user's accessible address space.
plars865695b2001-08-27 22:15:12 +000033 * 4) chown(2) returns -1 and sets errno to ENAMETOOLONG if the pathname
robbiew35e49062002-08-26 14:30:59 +000034 * component is too long.
plars865695b2001-08-27 22:15:12 +000035 * 5) chown(2) returns -1 and sets errno to ENOTDIR if the directory
robbiew35e49062002-08-26 14:30:59 +000036 * component in pathname is not a directory.
plars865695b2001-08-27 22:15:12 +000037 * 6) chown(2) returns -1 and sets errno to ENOENT if the specified file
robbiew35e49062002-08-26 14:30:59 +000038 * does not exists.
plars865695b2001-08-27 22:15:12 +000039 */
40
41#include <stdio.h>
42#include <stdlib.h>
43#include <unistd.h>
44#include <fcntl.h>
45#include <errno.h>
46#include <string.h>
47#include <signal.h>
48#include <grp.h>
49#include <pwd.h>
50#include <sys/types.h>
51#include <sys/stat.h>
plars1ad84512002-07-23 13:11:18 +000052#include <sys/mman.h>
Zeng Linggang2d127a32013-10-25 18:43:16 +080053#include <sys/mount.h>
plars865695b2001-08-27 22:15:12 +000054
55#include "test.h"
Zeng Linggang2d127a32013-10-25 18:43:16 +080056#include "safe_macros.h"
Han Pingtian75fb0572014-11-28 16:33:41 +080057#include "compat_16.h"
plars865695b2001-08-27 22:15:12 +000058
Garrett Cooperc0a39bb2010-12-17 16:06:03 -080059#define MODE_RWX (S_IRWXU|S_IRWXG|S_IRWXO)
60#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
Zeng Linggang2d127a32013-10-25 18:43:16 +080061#define DIR_MODE (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP| \
62 S_IXGRP|S_IROTH|S_IXOTH)
robbiew35e49062002-08-26 14:30:59 +000063#define DIR_TEMP "testdir_1"
64#define TEST_FILE1 "tfile_1"
Garrett Cooperc0a39bb2010-12-17 16:06:03 -080065#define TEST_FILE2 (DIR_TEMP "/tfile_2")
robbiew35e49062002-08-26 14:30:59 +000066#define TEST_FILE3 "t_file/tfile_3"
Zeng Linggang2d127a32013-10-25 18:43:16 +080067#define TEST_FILE4 "test_eloop1"
68#define TEST_FILE5 "mntpoint"
plars865695b2001-08-27 22:15:12 +000069
Cyril Hrubis75b30b62014-06-19 16:22:27 +020070static char long_path[PATH_MAX + 2];
Cyril Hrubisc0b8cc12014-06-19 16:52:32 +020071static const char *device;
Zeng Linggang2d127a32013-10-25 18:43:16 +080072static int mount_flag;
73
Cyril Hrubis75b30b62014-06-19 16:22:27 +020074static struct test_case_t {
subrata_modak56207ce2009-03-23 13:35:39 +000075 char *pathname;
subrata_modak56207ce2009-03-23 13:35:39 +000076 int exp_errno;
Cyril Hrubis75b30b62014-06-19 16:22:27 +020077} tc[] = {
78 {TEST_FILE1, EPERM},
79 {TEST_FILE2, EACCES},
80 {(char *)-1, EFAULT},
81 {long_path, ENAMETOOLONG},
82 {"", ENOENT},
83 {TEST_FILE3, ENOTDIR},
84 {TEST_FILE4, ELOOP},
85 {TEST_FILE5, EROFS}
86};
plars865695b2001-08-27 22:15:12 +000087
Han Pingtian75fb0572014-11-28 16:33:41 +080088TCID_DEFINE(chown04);
Cyril Hrubis75b30b62014-06-19 16:22:27 +020089int TST_TOTAL = ARRAY_SIZE(tc);
plars865695b2001-08-27 22:15:12 +000090
Cyril Hrubis75b30b62014-06-19 16:22:27 +020091static char *bad_addr;
robbiew6d8c9dc2001-08-31 18:34:37 +000092
Cyril Hrubis75b30b62014-06-19 16:22:27 +020093static void setup(void);
94static void cleanup(void);
plars1ad84512002-07-23 13:11:18 +000095
subrata_modak56207ce2009-03-23 13:35:39 +000096int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +000097{
Garrett Cooperc0a39bb2010-12-17 16:06:03 -080098 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020099 const char *msg;
Garrett Cooperc0a39bb2010-12-17 16:06:03 -0800100 int i;
101 uid_t user_id;
102 gid_t group_id;
plars865695b2001-08-27 22:15:12 +0000103
Cyril Hrubisc0b8cc12014-06-19 16:52:32 +0200104 msg = parse_opts(ac, av, NULL, NULL);
Zeng Linggang2d127a32013-10-25 18:43:16 +0800105 if (msg != NULL)
subrata_modak56207ce2009-03-23 13:35:39 +0000106 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Garrett Cooper2c282152010-12-16 00:55:50 -0800107
subrata_modak56207ce2009-03-23 13:35:39 +0000108 setup();
plars865695b2001-08-27 22:15:12 +0000109
Han Pingtian75fb0572014-11-28 16:33:41 +0800110 UID16_CHECK((user_id = geteuid()), "chown", cleanup)
111 GID16_CHECK((group_id = getegid()), "chown", cleanup)
plars865695b2001-08-27 22:15:12 +0000112
subrata_modak56207ce2009-03-23 13:35:39 +0000113 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800114 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000115
Garrett Cooperc0a39bb2010-12-17 16:06:03 -0800116 for (i = 0; i < TST_TOTAL; i++) {
Han Pingtian75fb0572014-11-28 16:33:41 +0800117 TEST(CHOWN(cleanup, tc[i].pathname, user_id, group_id));
plars865695b2001-08-27 22:15:12 +0000118
Garrett Cooperc0a39bb2010-12-17 16:06:03 -0800119 if (TEST_RETURN == 0) {
120 tst_resm(TFAIL, "chown succeeded unexpectedly");
subrata_modak56207ce2009-03-23 13:35:39 +0000121 continue;
Cyril Hrubis75b30b62014-06-19 16:22:27 +0200122 }
123
124 if (TEST_ERRNO == tc[i].exp_errno) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800125 tst_resm(TPASS | TTERRNO, "chown failed");
Cyril Hrubis75b30b62014-06-19 16:22:27 +0200126 } else {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800127 tst_resm(TFAIL | TTERRNO,
128 "chown failed; expected: %d - %s",
Cyril Hrubis75b30b62014-06-19 16:22:27 +0200129 tc[i].exp_errno,
130 tst_strerrno(tc[i].exp_errno));
subrata_modak56207ce2009-03-23 13:35:39 +0000131 }
Garrett Cooper2c282152010-12-16 00:55:50 -0800132 }
subrata_modak56207ce2009-03-23 13:35:39 +0000133 }
134
subrata_modak56207ce2009-03-23 13:35:39 +0000135 cleanup();
Garrett Cooperc0a39bb2010-12-17 16:06:03 -0800136 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800137}
plars865695b2001-08-27 22:15:12 +0000138
Cyril Hrubis75b30b62014-06-19 16:22:27 +0200139static void setup(void)
plars865695b2001-08-27 22:15:12 +0000140{
Cyril Hrubis75b30b62014-06-19 16:22:27 +0200141 struct passwd *ltpuser;
Cyril Hrubisc0b8cc12014-06-19 16:52:32 +0200142 const char *fs_type;
plars865695b2001-08-27 22:15:12 +0000143
Garrett Cooperc0a39bb2010-12-17 16:06:03 -0800144 tst_require_root(NULL);
subrata_modak56207ce2009-03-23 13:35:39 +0000145 tst_sig(FORK, DEF_HANDLER, cleanup);
Cyril Hrubisc0b8cc12014-06-19 16:52:32 +0200146 ltpuser = SAFE_GETPWNAM(NULL, "nobody");
plars865695b2001-08-27 22:15:12 +0000147
subrata_modak56207ce2009-03-23 13:35:39 +0000148 tst_tmpdir();
plars1ad84512002-07-23 13:11:18 +0000149
Cyril Hrubisc0b8cc12014-06-19 16:52:32 +0200150 fs_type = tst_dev_fs_type();
151 device = tst_acquire_device(cleanup);
152 if (!device)
153 tst_brkm(TCONF, cleanup, "Failed to obtain block device");
154
155 tst_mkfs(cleanup, device, fs_type, NULL);
156
157 TEST_PAUSE;
158
Cyril Hrubis75b30b62014-06-19 16:22:27 +0200159 memset(long_path, 'a', PATH_MAX - 1);
160
subrata_modak56207ce2009-03-23 13:35:39 +0000161 bad_addr = mmap(0, 1, PROT_NONE,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800162 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
Garrett Cooperc0a39bb2010-12-17 16:06:03 -0800163 if (bad_addr == MAP_FAILED)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800164 tst_brkm(TBROK | TERRNO, cleanup, "mmap failed");
plars1ad84512002-07-23 13:11:18 +0000165
Cyril Hrubis75b30b62014-06-19 16:22:27 +0200166 tc[2].pathname = bad_addr;
subrata_modak56207ce2009-03-23 13:35:39 +0000167
Zeng Linggang2d127a32013-10-25 18:43:16 +0800168 SAFE_SYMLINK(cleanup, "test_eloop1", "test_eloop2");
169 SAFE_SYMLINK(cleanup, "test_eloop2", "test_eloop1");
170
171 SAFE_SETEUID(cleanup, 0);
Cyril Hrubis75b30b62014-06-19 16:22:27 +0200172 SAFE_TOUCH(cleanup, "t_file", MODE_RWX, NULL);
173 SAFE_TOUCH(cleanup, TEST_FILE1, 0666, NULL);
174 SAFE_MKDIR(cleanup, DIR_TEMP, S_IRWXU);
175 SAFE_TOUCH(cleanup, TEST_FILE2, 0666, NULL);
176
Zeng Linggang2d127a32013-10-25 18:43:16 +0800177 SAFE_MKDIR(cleanup, "mntpoint", DIR_MODE);
Cyril Hrubisc0b8cc12014-06-19 16:52:32 +0200178 if (mount(device, "mntpoint", fs_type, MS_RDONLY, NULL) < 0) {
Zeng Linggang2d127a32013-10-25 18:43:16 +0800179 tst_brkm(TBROK | TERRNO, cleanup,
180 "mount device:%s failed", device);
181 }
182 mount_flag = 1;
183
184 SAFE_SETEUID(cleanup, ltpuser->pw_uid);
plars865695b2001-08-27 22:15:12 +0000185}
186
Mike Frysingerc57fba52014-04-09 18:56:30 -0400187void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000188{
Garrett Cooperc0a39bb2010-12-17 16:06:03 -0800189 if (seteuid(0) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800190 tst_resm(TWARN | TERRNO, "seteuid(0) failed");
Cyril Hrubis75b30b62014-06-19 16:22:27 +0200191
Cyril Hrubisc60a2302015-01-29 16:28:24 +0100192 if (mount_flag && tst_umount("mntpoint") < 0) {
Zeng Linggang2d127a32013-10-25 18:43:16 +0800193 tst_brkm(TBROK | TERRNO, NULL,
194 "umount device:%s failed", device);
195 }
robbiew35e49062002-08-26 14:30:59 +0000196
Cyril Hrubisc0b8cc12014-06-19 16:52:32 +0200197 if (device)
198 tst_release_device(NULL, device);
Zeng Linggang2d127a32013-10-25 18:43:16 +0800199
Cyril Hrubisc0b8cc12014-06-19 16:52:32 +0200200 tst_rmdir();
Zeng Linggang2d127a32013-10-25 18:43:16 +0800201}