blob: 3b2c45abb06415f4e2ae8ef8ba2df64f102d2446 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
plars865695b2001-08-27 22:15:12 +00002 * Copyright (c) International Business Machines Corp., 2001
Zeng Linggangd1043c92014-02-18 16:09:59 +08003 * 07/2001 Ported by Wayne Boyer
plars865695b2001-08-27 22:15:12 +00004 *
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
Zeng Linggangd1043c92014-02-18 16:09:59 +080016 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000018 */
plars865695b2001-08-27 22:15:12 +000019/*
plars865695b2001-08-27 22:15:12 +000020 * Test Description:
21 * Verify that,
22 * 1) lstat(2) returns -1 and sets errno to EACCES if search permission is
Zeng Linggangd1043c92014-02-18 16:09:59 +080023 * denied on a component of the path prefix.
plars865695b2001-08-27 22:15:12 +000024 * 2) lstat(2) returns -1 and sets errno to ENOENT if the specified file
25 * does not exists or empty string.
26 * 3) lstat(2) returns -1 and sets errno to EFAULT if pathname points
27 * outside user's accessible address space.
28 * 4) lstat(2) returns -1 and sets errno to ENAMETOOLONG if the pathname
29 * component is too long.
30 * 5) lstat(2) returns -1 and sets errno to ENOTDIR if the directory
31 * component in pathname is not a directory.
Zeng Linggang2f1458a2014-03-03 15:58:33 +080032 * 6) lstat(2) returns -1 and sets errno to ELOOP if the pathname has too
33 * many symbolic links encountered while traversing.
plars865695b2001-08-27 22:15:12 +000034 */
35
36#include <stdio.h>
37#include <stdlib.h>
38#include <unistd.h>
39#include <fcntl.h>
40#include <errno.h>
41#include <string.h>
42#include <signal.h>
43#include <sys/types.h>
44#include <sys/stat.h>
plars1ad84512002-07-23 13:11:18 +000045#include <sys/mman.h>
robbiew7bea8952001-09-04 20:05:43 +000046#include <pwd.h>
plars865695b2001-08-27 22:15:12 +000047
48#include "test.h"
Zeng Linggangd1043c92014-02-18 16:09:59 +080049#include "safe_macros.h"
plars865695b2001-08-27 22:15:12 +000050
51#define MODE_RWX S_IRWXU | S_IRWXG | S_IRWXO
52#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
Zeng Linggangd1043c92014-02-18 16:09:59 +080053#define TEST_DIR "test_dir"
54#define TEST_EACCES TEST_DIR"/test_eacces"
55#define TEST_ENOENT ""
56#define TEST_ENOTDIR "test_file/test_enotdir"
Zeng Linggang2f1458a2014-03-03 15:58:33 +080057#define TEST_ELOOP "/test_eloop"
plars865695b2001-08-27 22:15:12 +000058
Zeng Linggangd1043c92014-02-18 16:09:59 +080059static char longpathname[PATH_MAX + 2];
Zeng Linggang2f1458a2014-03-03 15:58:33 +080060static char elooppathname[sizeof(TEST_ELOOP) * 43] = ".";
robbiewd34d5812005-07-11 22:28:09 +000061
62#if !defined(UCLINUX)
Zeng Linggangd1043c92014-02-18 16:09:59 +080063static void bad_addr_setup(int);
64static void high_address_setup(int);
robbiewd34d5812005-07-11 22:28:09 +000065#endif
Zeng Linggangd1043c92014-02-18 16:09:59 +080066
67static struct test_case_t {
68 char *pathname;
69 int exp_errno;
70 void (*setup) ();
71} test_cases[] = {
72 {TEST_EACCES, EACCES, NULL},
73 {TEST_ENOENT, ENOENT, NULL},
74#if !defined(UCLINUX)
75 {NULL, EFAULT, bad_addr_setup},
76 {NULL, EFAULT, high_address_setup},
77#endif
78 {longpathname, ENAMETOOLONG, NULL},
79 {TEST_ENOTDIR, ENOTDIR, NULL},
Zeng Linggang2f1458a2014-03-03 15:58:33 +080080 {elooppathname, ELOOP, NULL},
plars865695b2001-08-27 22:15:12 +000081};
82
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020083char *TCID = "lstat02";
Zeng Linggangd1043c92014-02-18 16:09:59 +080084int TST_TOTAL = ARRAY_SIZE(test_cases);
plars865695b2001-08-27 22:15:12 +000085
Zeng Linggangd1043c92014-02-18 16:09:59 +080086static void setup(void);
87static void lstat_verify(int);
88static void cleanup(void);
plars865695b2001-08-27 22:15:12 +000089
subrata_modak56207ce2009-03-23 13:35:39 +000090int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +000091{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020092 int lc;
Zeng Linggangd1043c92014-02-18 16:09:59 +080093 int i;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020094 const char *msg;
plars865695b2001-08-27 22:15:12 +000095
Garrett Cooper45e285d2010-11-22 12:19:25 -080096 msg = parse_opts(ac, av, NULL, NULL);
Zeng Linggangd1043c92014-02-18 16:09:59 +080097 if (msg != NULL)
plars865695b2001-08-27 22:15:12 +000098 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Garrett Cooper2c282152010-12-16 00:55:50 -080099
plars865695b2001-08-27 22:15:12 +0000100 setup();
101
plars865695b2001-08-27 22:15:12 +0000102 for (lc = 0; TEST_LOOPING(lc); lc++) {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800103 tst_count = 0;
Zeng Linggangd1043c92014-02-18 16:09:59 +0800104 for (i = 0; i < TST_TOTAL; i++)
105 lstat_verify(i);
Garrett Cooper2c282152010-12-16 00:55:50 -0800106 }
plars865695b2001-08-27 22:15:12 +0000107
plars865695b2001-08-27 22:15:12 +0000108 cleanup();
Garrett Cooper1e6f5a62010-12-19 09:58:10 -0800109 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800110}
plars865695b2001-08-27 22:15:12 +0000111
Zeng Linggangd1043c92014-02-18 16:09:59 +0800112static void setup(void)
plars865695b2001-08-27 22:15:12 +0000113{
Zeng Linggang2f1458a2014-03-03 15:58:33 +0800114 int i;
Zeng Linggangd1043c92014-02-18 16:09:59 +0800115 struct passwd *ltpuser;
plars865695b2001-08-27 22:15:12 +0000116
Zeng Linggangd1043c92014-02-18 16:09:59 +0800117 tst_require_root(NULL);
plars865695b2001-08-27 22:15:12 +0000118
Zeng Linggangd1043c92014-02-18 16:09:59 +0800119 tst_sig(NOFORK, DEF_HANDLER, cleanup);
120
121 ltpuser = SAFE_GETPWNAM(cleanup, "nobody");
122 SAFE_SETEUID(cleanup, ltpuser->pw_uid);
plars865695b2001-08-27 22:15:12 +0000123
plars865695b2001-08-27 22:15:12 +0000124 TEST_PAUSE;
125
plars865695b2001-08-27 22:15:12 +0000126 tst_tmpdir();
127
Zeng Linggangd1043c92014-02-18 16:09:59 +0800128 SAFE_MKDIR(cleanup, TEST_DIR, MODE_RWX);
129 SAFE_TOUCH(cleanup, TEST_EACCES, 0666, NULL);
130 if (chmod(TEST_DIR, FILE_MODE) < 0)
131 tst_brkm(TBROK, cleanup, "chmod(2) of %s failed", TEST_DIR);
132
133 SAFE_TOUCH(cleanup, "test_file", MODE_RWX, NULL);
134
135 memset(longpathname, 'a', PATH_MAX+1);
Zeng Linggang2f1458a2014-03-03 15:58:33 +0800136
137 SAFE_MKDIR(cleanup, "test_eloop", MODE_RWX);
138 SAFE_SYMLINK(cleanup, "../test_eloop", "test_eloop/test_eloop");
139 /*
140 * NOTE: the ELOOP test is written based on that the consecutive
141 * symlinks limits in kernel is hardwired to 40.
142 */
143 for (i = 0; i < 43; i++)
144 strcat(elooppathname, TEST_ELOOP);
Zeng Linggangd1043c92014-02-18 16:09:59 +0800145}
146
vapier62b16cf2007-02-09 20:48:23 +0000147#if !defined(UCLINUX)
Zeng Linggangd1043c92014-02-18 16:09:59 +0800148static void bad_addr_setup(int i)
149{
150 test_cases[i].pathname = SAFE_MMAP(cleanup, 0, 1, PROT_NONE,
151 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
152}
153
154static void high_address_setup(int i)
155{
156 test_cases[i].pathname = (char *)get_high_address();
157}
mreed1081534c32006-08-03 05:21:24 +0000158#endif
plars1ad84512002-07-23 13:11:18 +0000159
Zeng Linggangd1043c92014-02-18 16:09:59 +0800160static void lstat_verify(int i)
161{
162 struct stat stat_buf;
163
164 if (test_cases[i].setup != NULL)
165 test_cases[i].setup(i);
166
167 TEST(lstat(test_cases[i].pathname, &stat_buf));
168
169 if (TEST_RETURN != -1) {
170 tst_resm(TFAIL, "lstat() returned %ld, expected -1, errno=%d",
171 TEST_RETURN, test_cases[i].exp_errno);
172 return;
173 }
174
Zeng Linggangd1043c92014-02-18 16:09:59 +0800175 if (TEST_ERRNO == test_cases[i].exp_errno) {
176 tst_resm(TPASS | TTERRNO, "lstat() failed as expected");
177 } else {
178 tst_resm(TFAIL | TTERRNO,
179 "lstat() failed unexpectedly; expected: %d - %s",
180 test_cases[i].exp_errno,
181 strerror(test_cases[i].exp_errno));
plars865695b2001-08-27 22:15:12 +0000182 }
183}
184
Zeng Linggangd1043c92014-02-18 16:09:59 +0800185static void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000186{
Zeng Linggangd1043c92014-02-18 16:09:59 +0800187 if (seteuid(0))
188 tst_resm(TINFO | TERRNO, "Failet to seteuid(0) before cleanup");
plars865695b2001-08-27 22:15:12 +0000189
plars865695b2001-08-27 22:15:12 +0000190 tst_rmdir();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700191}