blob: ce9a9e647bca8a345d592da2304e70fbc650ddc0 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
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
plars865695b2001-08-27 22:15:12 +000018 */
19
20/*
plars865695b2001-08-27 22:15:12 +000021 * Test Description:
22 * Verify that,
23 * 1. access() fails with -1 return value and sets errno to EACCES
24 * if the permission bits of the file mode do not permit the
25 * requested (Read/Write/Execute) access.
26 * 2. access() fails with -1 return value and sets errno to EINVAL
27 * if the specified access mode argument is invalid.
28 * 3. access() fails with -1 return value and sets errno to EFAULT
29 * if the pathname points outside allocate address space for the
30 * process.
31 * 4. access() fails with -1 return value and sets errno to ENOENT
32 * if the specified file doesn't exist (or pathname is NULL).
33 * 5. access() fails with -1 return value and sets errno to ENAMETOOLONG
34 * if the pathname size is > PATH_MAX characters.
Wang, Xiaoguang/王 小光c7b23c22013-11-05 13:51:47 +080035 * 6. access() fails with -1 return value and sets errno to ENOTDIR
36 * if a component used as a directory in pathname is not a directory.
37 * 7. access() fails with -1 return value and sets errno to ELOOP
38 * if too many symbolic links were encountered in resolving pathname.
plars865695b2001-08-27 22:15:12 +000039 *
Wanlong Gaob3e9e5e2013-04-26 14:55:25 +080040 * 07/2001 Ported by Wayne Boyer
plars865695b2001-08-27 22:15:12 +000041 */
42
43#include <stdio.h>
44#include <errno.h>
45#include <unistd.h>
46#include <fcntl.h>
47#include <string.h>
48#include <signal.h>
49#include <sys/types.h>
50#include <sys/stat.h>
plars1ad84512002-07-23 13:11:18 +000051#include <sys/mman.h>
robbiew73c2db72001-09-05 16:49:27 +000052#include <pwd.h>
plars865695b2001-08-27 22:15:12 +000053
54#include "test.h"
Wang, Xiaoguang49e58682013-10-21 16:30:16 +080055#include "safe_macros.h"
plars865695b2001-08-27 22:15:12 +000056
57#define INV_OK -1
58#define TEST_FILE1 "test_file1"
59#define TEST_FILE2 "test_file2"
60#define TEST_FILE3 "test_file3"
61#define TEST_FILE4 "test_file4"
Wang, Xiaoguang/王 小光c7b23c22013-11-05 13:51:47 +080062#define TEST_FILE5 "test_file5/test_file5"
63#define TEST_FILE6 "test_file6"
plars865695b2001-08-27 22:15:12 +000064
plars865695b2001-08-27 22:15:12 +000065
robbiewd34d5812005-07-11 22:28:09 +000066#if !defined(UCLINUX)
Wanlong Gaob3e9e5e2013-04-26 14:55:25 +080067static char high_address_node[64];
robbiewd34d5812005-07-11 22:28:09 +000068#endif
robbiew15226cd2002-04-10 16:10:40 +000069
Wanlong Gaob3e9e5e2013-04-26 14:55:25 +080070static char longpathname[PATH_MAX + 2];
plars865695b2001-08-27 22:15:12 +000071
Wanlong Gaob3e9e5e2013-04-26 14:55:25 +080072static struct test_case_t {
plars865695b2001-08-27 22:15:12 +000073 char *pathname;
74 int a_mode;
plars865695b2001-08-27 22:15:12 +000075 int exp_errno;
Garrett Cooper187e27c2010-12-17 13:30:26 -080076} test_cases[] = {
Wang, Xiaoguang49e58682013-10-21 16:30:16 +080077 {TEST_FILE1, R_OK, EACCES},
78 {TEST_FILE2, W_OK, EACCES},
79 {TEST_FILE3, X_OK, EACCES},
80 {TEST_FILE4, INV_OK, EINVAL},
robbiewd34d5812005-07-11 22:28:09 +000081#if !defined(UCLINUX)
Wang, Xiaoguang49e58682013-10-21 16:30:16 +080082 {(char *)-1, R_OK, EFAULT},
83 {high_address_node, R_OK, EFAULT},
robbiewd34d5812005-07-11 22:28:09 +000084#endif
Wang, Xiaoguang49e58682013-10-21 16:30:16 +080085 {"", W_OK, ENOENT},
86 {longpathname, R_OK, ENAMETOOLONG},
Wang, Xiaoguang/王 小光c7b23c22013-11-05 13:51:47 +080087 {TEST_FILE5, R_OK, ENOTDIR},
88 {TEST_FILE6, R_OK, ELOOP},
Wanlong Gaob3e9e5e2013-04-26 14:55:25 +080089};
plars865695b2001-08-27 22:15:12 +000090
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020091char *TCID = "access05";
Wang, Xiaoguang49e58682013-10-21 16:30:16 +080092int TST_TOTAL = ARRAY_SIZE(test_cases);
plars865695b2001-08-27 22:15:12 +000093
Wanlong Gaob3e9e5e2013-04-26 14:55:25 +080094static const char nobody_uid[] = "nobody";
95static struct passwd *ltpuser;
plars865695b2001-08-27 22:15:12 +000096
Wanlong Gaob3e9e5e2013-04-26 14:55:25 +080097static void setup(void);
Wang, Xiaoguang49e58682013-10-21 16:30:16 +080098static void access_verify(int i);
Wanlong Gaob3e9e5e2013-04-26 14:55:25 +080099static void cleanup(void);
100
101static char *bad_addr;
plars1ad84512002-07-23 13:11:18 +0000102
subrata_modak56207ce2009-03-23 13:35:39 +0000103int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000104{
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200105 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200106 const char *msg;
Garrett Cooper187e27c2010-12-17 13:30:26 -0800107 int i;
plars865695b2001-08-27 22:15:12 +0000108
Wanlong Gaob3e9e5e2013-04-26 14:55:25 +0800109 msg = parse_opts(ac, av, NULL, NULL);
110 if (msg != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -0800111 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
plars865695b2001-08-27 22:15:12 +0000112
plars865695b2001-08-27 22:15:12 +0000113 setup();
114
plars865695b2001-08-27 22:15:12 +0000115 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800116 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000117
Wang, Xiaoguang49e58682013-10-21 16:30:16 +0800118 for (i = 0; i < TST_TOTAL; i++)
119 access_verify(i);
Garrett Cooper2c282152010-12-16 00:55:50 -0800120 }
plars865695b2001-08-27 22:15:12 +0000121
plars865695b2001-08-27 22:15:12 +0000122 cleanup();
Garrett Cooper187e27c2010-12-17 13:30:26 -0800123 tst_exit();
Garrett Cooper187e27c2010-12-17 13:30:26 -0800124}
125
Wanlong Gaob3e9e5e2013-04-26 14:55:25 +0800126static void setup(void)
plars865695b2001-08-27 22:15:12 +0000127{
Wang, Xiaoguang49e58682013-10-21 16:30:16 +0800128 int fd;
plars865695b2001-08-27 22:15:12 +0000129
plars865695b2001-08-27 22:15:12 +0000130 tst_sig(NOFORK, DEF_HANDLER, cleanup);
Garrett Cooper187e27c2010-12-17 13:30:26 -0800131 tst_require_root(NULL);
132
Wang, Xiaoguang49e58682013-10-21 16:30:16 +0800133 ltpuser = SAFE_GETPWNAM(cleanup, nobody_uid);
134 SAFE_SETUID(cleanup, ltpuser->pw_uid);
plars865695b2001-08-27 22:15:12 +0000135 TEST_PAUSE;
136
vapier62b16cf2007-02-09 20:48:23 +0000137#if !defined(UCLINUX)
robbiewd34d5812005-07-11 22:28:09 +0000138 bad_addr = mmap(0, 1, PROT_NONE,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800139 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
Garrett Cooper187e27c2010-12-17 13:30:26 -0800140 if (bad_addr == MAP_FAILED)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800141 tst_brkm(TBROK | TERRNO, NULL, "mmap failed");
Wang, Xiaoguang49e58682013-10-21 16:30:16 +0800142 test_cases[4].pathname = bad_addr;
143
144 test_cases[5].pathname = get_high_address();
mreed1081534c32006-08-03 05:21:24 +0000145#endif
plars1ad84512002-07-23 13:11:18 +0000146
Garrett Cooper187e27c2010-12-17 13:30:26 -0800147 tst_tmpdir();
148
Wang, Xiaoguang49e58682013-10-21 16:30:16 +0800149 /*
150 * create TEST_FILE1 to test R_OK EACCESS
151 */
152 fd = SAFE_CREAT(cleanup, TEST_FILE1, 0333);
153 SAFE_CLOSE(cleanup, fd);
154
155 /*
156 * create TEST_FILE2 to test W_OK EACCESS
157 */
158 fd = SAFE_CREAT(cleanup, TEST_FILE2, 0555);
159 SAFE_CLOSE(cleanup, fd);
160
161 /*
162 * create TEST_FILE3 to test X_OK EACCESS
163 */
164 fd = SAFE_CREAT(cleanup, TEST_FILE3, 0666);
165 SAFE_CLOSE(cleanup, fd);
166
167 /*
168 * create TEST_FILE4 to test EINVAL
169 */
170 fd = SAFE_CREAT(cleanup, TEST_FILE4, 0333);
171 SAFE_CLOSE(cleanup, fd);
172
173 /*
174 *setup to create a node with a name length exceeding
175 *the MAX length of PATH_MAX.
176 */
177 memset(longpathname, 'a', sizeof(longpathname) - 1);
Wang, Xiaoguang/王 小光c7b23c22013-11-05 13:51:47 +0800178
179 /* create test_file5 for test ENOTDIR. */
180 SAFE_TOUCH(cleanup, "test_file5", 0644, NULL);
181
182 /*
183 * create two symbolic links who point to each other for
184 * test ELOOP.
185 */
186 SAFE_SYMLINK(cleanup, "test_file6", "test_file7");
187 SAFE_SYMLINK(cleanup, "test_file7", "test_file6");
plars865695b2001-08-27 22:15:12 +0000188}
189
Wang, Xiaoguang49e58682013-10-21 16:30:16 +0800190static void access_verify(int i)
vapier6f550172009-08-28 10:46:41 +0000191{
Wang, Xiaoguang49e58682013-10-21 16:30:16 +0800192 char *file_name;
193 int access_mode;
vapier6f550172009-08-28 10:46:41 +0000194
Wang, Xiaoguang49e58682013-10-21 16:30:16 +0800195 file_name = test_cases[i].pathname;
196 access_mode = test_cases[i].a_mode;
vapier6f550172009-08-28 10:46:41 +0000197
Wang, Xiaoguang49e58682013-10-21 16:30:16 +0800198 TEST(access(file_name, access_mode));
plars865695b2001-08-27 22:15:12 +0000199
Wang, Xiaoguang49e58682013-10-21 16:30:16 +0800200 if (TEST_RETURN != -1) {
201 tst_resm(TFAIL, "access(%s, %#o) succeeded unexpectedly",
202 file_name, access_mode);
203 return;
204 }
plars865695b2001-08-27 22:15:12 +0000205
Wang, Xiaoguang49e58682013-10-21 16:30:16 +0800206 if (TEST_ERRNO == test_cases[i].exp_errno) {
207 tst_resm(TPASS | TTERRNO, "access failed as expected");
208 } else {
209 tst_resm(TFAIL | TTERRNO,
210 "access failed unexpectedly; expected: "
211 "%d - %s", test_cases[i].exp_errno,
212 strerror(test_cases[i].exp_errno));
213 }
plars865695b2001-08-27 22:15:12 +0000214}
215
Wanlong Gaob3e9e5e2013-04-26 14:55:25 +0800216static void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000217{
plars865695b2001-08-27 22:15:12 +0000218 tst_rmdir();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700219}