1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) 2014 Fujitsu Ltd.
3*49cdfc7eSAndroid Build Coastguard Worker * Author: Zeng Linggang <[email protected]>
4*49cdfc7eSAndroid Build Coastguard Worker *
5*49cdfc7eSAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or modify it
6*49cdfc7eSAndroid Build Coastguard Worker * under the terms of version 2 of the GNU General Public License as
7*49cdfc7eSAndroid Build Coastguard Worker * published by the Free Software Foundation.
8*49cdfc7eSAndroid Build Coastguard Worker *
9*49cdfc7eSAndroid Build Coastguard Worker * This program is distributed in the hope that it would be useful, but
10*49cdfc7eSAndroid Build Coastguard Worker * WITHOUT ANY WARRANTY; without even the implied warranty of
11*49cdfc7eSAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12*49cdfc7eSAndroid Build Coastguard Worker *
13*49cdfc7eSAndroid Build Coastguard Worker * You should have received a copy of the GNU General Public License along
14*49cdfc7eSAndroid Build Coastguard Worker * with this program.
15*49cdfc7eSAndroid Build Coastguard Worker */
16*49cdfc7eSAndroid Build Coastguard Worker /*
17*49cdfc7eSAndroid Build Coastguard Worker * Test that linkat() fails and sets the proper errno values.
18*49cdfc7eSAndroid Build Coastguard Worker */
19*49cdfc7eSAndroid Build Coastguard Worker
20*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
21*49cdfc7eSAndroid Build Coastguard Worker
22*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
23*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
24*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
25*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
26*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
27*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
28*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h>
29*49cdfc7eSAndroid Build Coastguard Worker #include <pwd.h>
30*49cdfc7eSAndroid Build Coastguard Worker #include <sys/mount.h>
31*49cdfc7eSAndroid Build Coastguard Worker
32*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
33*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/syscalls.h"
34*49cdfc7eSAndroid Build Coastguard Worker #include "safe_macros.h"
35*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/fcntl.h"
36*49cdfc7eSAndroid Build Coastguard Worker
37*49cdfc7eSAndroid Build Coastguard Worker #define DIR_MODE (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP| \
38*49cdfc7eSAndroid Build Coastguard Worker S_IXGRP|S_IROTH|S_IXOTH)
39*49cdfc7eSAndroid Build Coastguard Worker #define TEST_FILE "testfile"
40*49cdfc7eSAndroid Build Coastguard Worker #define TEST_EXIST "testexist"
41*49cdfc7eSAndroid Build Coastguard Worker #define TEST_ELOOP "testeloop"
42*49cdfc7eSAndroid Build Coastguard Worker #define TEST_EACCES "./tmp/testeeacces"
43*49cdfc7eSAndroid Build Coastguard Worker #define TEST_EACCES2 "./tmp/testeeacces2"
44*49cdfc7eSAndroid Build Coastguard Worker #define TEST_EROFS "mntpoint"
45*49cdfc7eSAndroid Build Coastguard Worker #define TEST_EROFS2 "mntpoint/testerofs2"
46*49cdfc7eSAndroid Build Coastguard Worker #define TEST_EMLINK "emlink_dir/testfile0"
47*49cdfc7eSAndroid Build Coastguard Worker #define TEST_EMLINK2 "emlink_dir/testfile"
48*49cdfc7eSAndroid Build Coastguard Worker #define BASENAME "mntpoint/basename"
49*49cdfc7eSAndroid Build Coastguard Worker
50*49cdfc7eSAndroid Build Coastguard Worker static char nametoolong[PATH_MAX+2];
51*49cdfc7eSAndroid Build Coastguard Worker static const char *device;
52*49cdfc7eSAndroid Build Coastguard Worker static int mount_flag;
53*49cdfc7eSAndroid Build Coastguard Worker static int max_hardlinks;
54*49cdfc7eSAndroid Build Coastguard Worker static const char *fs_type;
55*49cdfc7eSAndroid Build Coastguard Worker
56*49cdfc7eSAndroid Build Coastguard Worker static void setup(void);
57*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void);
58*49cdfc7eSAndroid Build Coastguard Worker static void setup_eacces(void);
59*49cdfc7eSAndroid Build Coastguard Worker static void cleanup_eacces(void);
60*49cdfc7eSAndroid Build Coastguard Worker static void setup_erofs(void);
61*49cdfc7eSAndroid Build Coastguard Worker
62*49cdfc7eSAndroid Build Coastguard Worker static struct test_struct {
63*49cdfc7eSAndroid Build Coastguard Worker const char *oldfname;
64*49cdfc7eSAndroid Build Coastguard Worker const char *newfname;
65*49cdfc7eSAndroid Build Coastguard Worker int flags;
66*49cdfc7eSAndroid Build Coastguard Worker int expected_errno;
67*49cdfc7eSAndroid Build Coastguard Worker void (*setupfunc) (void);
68*49cdfc7eSAndroid Build Coastguard Worker void (*cleanfunc) (void);
69*49cdfc7eSAndroid Build Coastguard Worker } test_cases[] = {
70*49cdfc7eSAndroid Build Coastguard Worker {TEST_FILE, nametoolong, 0, ENAMETOOLONG, NULL, NULL},
71*49cdfc7eSAndroid Build Coastguard Worker {nametoolong, TEST_FILE, 0, ENAMETOOLONG, NULL, NULL},
72*49cdfc7eSAndroid Build Coastguard Worker {TEST_EXIST, TEST_EXIST, 0, EEXIST, NULL, NULL},
73*49cdfc7eSAndroid Build Coastguard Worker {TEST_ELOOP, TEST_FILE, AT_SYMLINK_FOLLOW, ELOOP, NULL, NULL},
74*49cdfc7eSAndroid Build Coastguard Worker {TEST_EACCES, TEST_EACCES2, 0, EACCES, setup_eacces, cleanup_eacces},
75*49cdfc7eSAndroid Build Coastguard Worker {TEST_EROFS, TEST_EROFS2, 0, EROFS, setup_erofs, NULL},
76*49cdfc7eSAndroid Build Coastguard Worker {TEST_EMLINK, TEST_EMLINK2, 0, EMLINK, NULL, NULL},
77*49cdfc7eSAndroid Build Coastguard Worker };
78*49cdfc7eSAndroid Build Coastguard Worker
79*49cdfc7eSAndroid Build Coastguard Worker char *TCID = "linkat02";
80*49cdfc7eSAndroid Build Coastguard Worker int TST_TOTAL = ARRAY_SIZE(test_cases);
81*49cdfc7eSAndroid Build Coastguard Worker
82*49cdfc7eSAndroid Build Coastguard Worker static struct passwd *ltpuser;
83*49cdfc7eSAndroid Build Coastguard Worker static void linkat_verify(const struct test_struct *);
84*49cdfc7eSAndroid Build Coastguard Worker
main(int ac,char ** av)85*49cdfc7eSAndroid Build Coastguard Worker int main(int ac, char **av)
86*49cdfc7eSAndroid Build Coastguard Worker {
87*49cdfc7eSAndroid Build Coastguard Worker int lc;
88*49cdfc7eSAndroid Build Coastguard Worker int i;
89*49cdfc7eSAndroid Build Coastguard Worker
90*49cdfc7eSAndroid Build Coastguard Worker tst_parse_opts(ac, av, NULL, NULL);
91*49cdfc7eSAndroid Build Coastguard Worker
92*49cdfc7eSAndroid Build Coastguard Worker setup();
93*49cdfc7eSAndroid Build Coastguard Worker
94*49cdfc7eSAndroid Build Coastguard Worker for (lc = 0; TEST_LOOPING(lc); lc++) {
95*49cdfc7eSAndroid Build Coastguard Worker tst_count = 0;
96*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < TST_TOTAL; i++)
97*49cdfc7eSAndroid Build Coastguard Worker linkat_verify(&test_cases[i]);
98*49cdfc7eSAndroid Build Coastguard Worker }
99*49cdfc7eSAndroid Build Coastguard Worker
100*49cdfc7eSAndroid Build Coastguard Worker cleanup();
101*49cdfc7eSAndroid Build Coastguard Worker tst_exit();
102*49cdfc7eSAndroid Build Coastguard Worker }
103*49cdfc7eSAndroid Build Coastguard Worker
linkat_verify(const struct test_struct * desc)104*49cdfc7eSAndroid Build Coastguard Worker static void linkat_verify(const struct test_struct *desc)
105*49cdfc7eSAndroid Build Coastguard Worker {
106*49cdfc7eSAndroid Build Coastguard Worker if (desc->expected_errno == EMLINK && max_hardlinks == 0) {
107*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TCONF, "EMLINK test is not appropriate");
108*49cdfc7eSAndroid Build Coastguard Worker return;
109*49cdfc7eSAndroid Build Coastguard Worker }
110*49cdfc7eSAndroid Build Coastguard Worker
111*49cdfc7eSAndroid Build Coastguard Worker if (desc->setupfunc != NULL) {
112*49cdfc7eSAndroid Build Coastguard Worker desc->setupfunc();
113*49cdfc7eSAndroid Build Coastguard Worker }
114*49cdfc7eSAndroid Build Coastguard Worker
115*49cdfc7eSAndroid Build Coastguard Worker TEST(tst_syscall(__NR_linkat, AT_FDCWD, desc->oldfname,
116*49cdfc7eSAndroid Build Coastguard Worker AT_FDCWD, desc->newfname, desc->flags));
117*49cdfc7eSAndroid Build Coastguard Worker
118*49cdfc7eSAndroid Build Coastguard Worker if (desc->cleanfunc != NULL)
119*49cdfc7eSAndroid Build Coastguard Worker desc->cleanfunc();
120*49cdfc7eSAndroid Build Coastguard Worker
121*49cdfc7eSAndroid Build Coastguard Worker if (TEST_RETURN != -1) {
122*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TFAIL,
123*49cdfc7eSAndroid Build Coastguard Worker "linkat(""AT_FDCWD"", %s, ""AT_FDCWD"", %s, %d) "
124*49cdfc7eSAndroid Build Coastguard Worker "succeeded unexpectedly", desc->oldfname,
125*49cdfc7eSAndroid Build Coastguard Worker desc->newfname, desc->flags);
126*49cdfc7eSAndroid Build Coastguard Worker return;
127*49cdfc7eSAndroid Build Coastguard Worker }
128*49cdfc7eSAndroid Build Coastguard Worker
129*49cdfc7eSAndroid Build Coastguard Worker if (TEST_ERRNO == desc->expected_errno) {
130*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TPASS | TTERRNO, "linkat failed as expected");
131*49cdfc7eSAndroid Build Coastguard Worker } else {
132*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TFAIL | TTERRNO,
133*49cdfc7eSAndroid Build Coastguard Worker "linkat failed unexpectedly; expected: "
134*49cdfc7eSAndroid Build Coastguard Worker "%d - %s", desc->expected_errno,
135*49cdfc7eSAndroid Build Coastguard Worker strerror(desc->expected_errno));
136*49cdfc7eSAndroid Build Coastguard Worker }
137*49cdfc7eSAndroid Build Coastguard Worker }
138*49cdfc7eSAndroid Build Coastguard Worker
setup(void)139*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
140*49cdfc7eSAndroid Build Coastguard Worker {
141*49cdfc7eSAndroid Build Coastguard Worker tst_require_root();
142*49cdfc7eSAndroid Build Coastguard Worker
143*49cdfc7eSAndroid Build Coastguard Worker tst_sig(NOFORK, DEF_HANDLER, cleanup);
144*49cdfc7eSAndroid Build Coastguard Worker
145*49cdfc7eSAndroid Build Coastguard Worker tst_tmpdir();
146*49cdfc7eSAndroid Build Coastguard Worker
147*49cdfc7eSAndroid Build Coastguard Worker fs_type = tst_dev_fs_type();
148*49cdfc7eSAndroid Build Coastguard Worker device = tst_acquire_device(cleanup);
149*49cdfc7eSAndroid Build Coastguard Worker
150*49cdfc7eSAndroid Build Coastguard Worker if (!device)
151*49cdfc7eSAndroid Build Coastguard Worker tst_brkm(TCONF, cleanup, "Failed to acquire device");
152*49cdfc7eSAndroid Build Coastguard Worker
153*49cdfc7eSAndroid Build Coastguard Worker TEST_PAUSE;
154*49cdfc7eSAndroid Build Coastguard Worker
155*49cdfc7eSAndroid Build Coastguard Worker ltpuser = SAFE_GETPWNAM(cleanup, "nobody");
156*49cdfc7eSAndroid Build Coastguard Worker
157*49cdfc7eSAndroid Build Coastguard Worker SAFE_TOUCH(cleanup, TEST_FILE, 0644, NULL);
158*49cdfc7eSAndroid Build Coastguard Worker
159*49cdfc7eSAndroid Build Coastguard Worker memset(nametoolong, 'a', PATH_MAX+1);
160*49cdfc7eSAndroid Build Coastguard Worker
161*49cdfc7eSAndroid Build Coastguard Worker SAFE_TOUCH(cleanup, TEST_EXIST, 0644, NULL);
162*49cdfc7eSAndroid Build Coastguard Worker
163*49cdfc7eSAndroid Build Coastguard Worker SAFE_SYMLINK(cleanup, TEST_ELOOP, "test_file_eloop2");
164*49cdfc7eSAndroid Build Coastguard Worker SAFE_SYMLINK(cleanup, "test_file_eloop2", TEST_ELOOP);
165*49cdfc7eSAndroid Build Coastguard Worker
166*49cdfc7eSAndroid Build Coastguard Worker SAFE_MKDIR(cleanup, "./tmp", DIR_MODE);
167*49cdfc7eSAndroid Build Coastguard Worker SAFE_TOUCH(cleanup, TEST_EACCES, 0666, NULL);
168*49cdfc7eSAndroid Build Coastguard Worker
169*49cdfc7eSAndroid Build Coastguard Worker tst_mkfs(cleanup, device, fs_type, NULL, NULL);
170*49cdfc7eSAndroid Build Coastguard Worker SAFE_MKDIR(cleanup, "mntpoint", DIR_MODE);
171*49cdfc7eSAndroid Build Coastguard Worker
172*49cdfc7eSAndroid Build Coastguard Worker SAFE_MOUNT(cleanup, device, "mntpoint", fs_type, 0, NULL);
173*49cdfc7eSAndroid Build Coastguard Worker mount_flag = 1;
174*49cdfc7eSAndroid Build Coastguard Worker
175*49cdfc7eSAndroid Build Coastguard Worker max_hardlinks = tst_fs_fill_hardlinks(cleanup, "emlink_dir");
176*49cdfc7eSAndroid Build Coastguard Worker }
177*49cdfc7eSAndroid Build Coastguard Worker
setup_eacces(void)178*49cdfc7eSAndroid Build Coastguard Worker static void setup_eacces(void)
179*49cdfc7eSAndroid Build Coastguard Worker {
180*49cdfc7eSAndroid Build Coastguard Worker SAFE_SETEUID(cleanup, ltpuser->pw_uid);
181*49cdfc7eSAndroid Build Coastguard Worker }
182*49cdfc7eSAndroid Build Coastguard Worker
cleanup_eacces(void)183*49cdfc7eSAndroid Build Coastguard Worker static void cleanup_eacces(void)
184*49cdfc7eSAndroid Build Coastguard Worker {
185*49cdfc7eSAndroid Build Coastguard Worker SAFE_SETEUID(cleanup, 0);
186*49cdfc7eSAndroid Build Coastguard Worker }
187*49cdfc7eSAndroid Build Coastguard Worker
setup_erofs(void)188*49cdfc7eSAndroid Build Coastguard Worker static void setup_erofs(void)
189*49cdfc7eSAndroid Build Coastguard Worker {
190*49cdfc7eSAndroid Build Coastguard Worker SAFE_MOUNT(cleanup, device, "mntpoint", fs_type,
191*49cdfc7eSAndroid Build Coastguard Worker MS_REMOUNT | MS_RDONLY, NULL);
192*49cdfc7eSAndroid Build Coastguard Worker mount_flag = 1;
193*49cdfc7eSAndroid Build Coastguard Worker }
194*49cdfc7eSAndroid Build Coastguard Worker
cleanup(void)195*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
196*49cdfc7eSAndroid Build Coastguard Worker {
197*49cdfc7eSAndroid Build Coastguard Worker if (mount_flag && tst_umount("mntpoint") < 0)
198*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TWARN | TERRNO, "umount device:%s failed", device);
199*49cdfc7eSAndroid Build Coastguard Worker
200*49cdfc7eSAndroid Build Coastguard Worker if (device)
201*49cdfc7eSAndroid Build Coastguard Worker tst_release_device(device);
202*49cdfc7eSAndroid Build Coastguard Worker
203*49cdfc7eSAndroid Build Coastguard Worker tst_rmdir();
204*49cdfc7eSAndroid Build Coastguard Worker }
205