xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/fsetxattr/fsetxattr01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) 2018 Linaro Limited. All rights reserved.
4*49cdfc7eSAndroid Build Coastguard Worker  * Author: Rafael David Tinoco <[email protected]>
5*49cdfc7eSAndroid Build Coastguard Worker  */
6*49cdfc7eSAndroid Build Coastguard Worker 
7*49cdfc7eSAndroid Build Coastguard Worker /*
8*49cdfc7eSAndroid Build Coastguard Worker  * Basic tests for fsetxattr(2) and make sure fsetxattr(2) handles error
9*49cdfc7eSAndroid Build Coastguard Worker  * conditions correctly.
10*49cdfc7eSAndroid Build Coastguard Worker  *
11*49cdfc7eSAndroid Build Coastguard Worker  * There are 9 test cases:
12*49cdfc7eSAndroid Build Coastguard Worker  * 1. Any other flags being set except XATTR_CREATE and XATTR_REPLACE,
13*49cdfc7eSAndroid Build Coastguard Worker  *    fsetxattr(2) should return -1 and set errno to EINVAL
14*49cdfc7eSAndroid Build Coastguard Worker  * 2. With XATTR_REPLACE flag set but the attribute does not exist,
15*49cdfc7eSAndroid Build Coastguard Worker  *    fsetxattr(2) should return -1 and set errno to ENODATA
16*49cdfc7eSAndroid Build Coastguard Worker  * 3. Create new attr with name length greater than XATTR_NAME_MAX(255)
17*49cdfc7eSAndroid Build Coastguard Worker  *    fsetxattr(2) should return -1 and set errno to ERANGE
18*49cdfc7eSAndroid Build Coastguard Worker  * 4. Create new attr whose value length is greater than XATTR_SIZE_MAX(65536)
19*49cdfc7eSAndroid Build Coastguard Worker  *    fsetxattr(2) should return -1 and set errno to E2BIG
20*49cdfc7eSAndroid Build Coastguard Worker  * 5. Create new attr whose value length is zero,
21*49cdfc7eSAndroid Build Coastguard Worker  *    fsetxattr(2) should succeed
22*49cdfc7eSAndroid Build Coastguard Worker  * 6. Replace the attr value without XATTR_REPLACE flag being set,
23*49cdfc7eSAndroid Build Coastguard Worker  *    fsetxattr(2) should return -1 and set errno to EEXIST
24*49cdfc7eSAndroid Build Coastguard Worker  * 7. Replace attr value with XATTR_REPLACE flag being set,
25*49cdfc7eSAndroid Build Coastguard Worker  *    fsetxattr(2) should succeed
26*49cdfc7eSAndroid Build Coastguard Worker  * 8. Create new attr whose key length is zero,
27*49cdfc7eSAndroid Build Coastguard Worker  *    fsetxattr(2) should return -1 and set errno to ERANGE
28*49cdfc7eSAndroid Build Coastguard Worker  * 9. Create new attr whose key is NULL,
29*49cdfc7eSAndroid Build Coastguard Worker  *    fsetxattr(2) should return -1 and set errno to EFAULT
30*49cdfc7eSAndroid Build Coastguard Worker  */
31*49cdfc7eSAndroid Build Coastguard Worker 
32*49cdfc7eSAndroid Build Coastguard Worker #include "config.h"
33*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
34*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
35*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
36*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
37*49cdfc7eSAndroid Build Coastguard Worker #include <fcntl.h>
38*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
39*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h>
40*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
41*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
42*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
43*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_SYS_XATTR_H
44*49cdfc7eSAndroid Build Coastguard Worker # include <sys/xattr.h>
45*49cdfc7eSAndroid Build Coastguard Worker #endif
46*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
47*49cdfc7eSAndroid Build Coastguard Worker 
48*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_SYS_XATTR_H
49*49cdfc7eSAndroid Build Coastguard Worker #define XATTR_NAME_MAX 255
50*49cdfc7eSAndroid Build Coastguard Worker #define XATTR_NAME_LEN (XATTR_NAME_MAX + 2)
51*49cdfc7eSAndroid Build Coastguard Worker #define XATTR_SIZE_MAX 65536
52*49cdfc7eSAndroid Build Coastguard Worker #define XATTR_TEST_KEY "user.testkey"
53*49cdfc7eSAndroid Build Coastguard Worker #define XATTR_TEST_VALUE "this is a test value"
54*49cdfc7eSAndroid Build Coastguard Worker #define XATTR_TEST_VALUE_SIZE 20
55*49cdfc7eSAndroid Build Coastguard Worker #define MNTPOINT "mntpoint"
56*49cdfc7eSAndroid Build Coastguard Worker #define FNAME MNTPOINT"/fsetxattr01testfile"
57*49cdfc7eSAndroid Build Coastguard Worker 
58*49cdfc7eSAndroid Build Coastguard Worker static int fd = -1;
59*49cdfc7eSAndroid Build Coastguard Worker static char long_key[XATTR_NAME_LEN];
60*49cdfc7eSAndroid Build Coastguard Worker static char *long_value;
61*49cdfc7eSAndroid Build Coastguard Worker static char *xattr_value = XATTR_TEST_VALUE;
62*49cdfc7eSAndroid Build Coastguard Worker 
63*49cdfc7eSAndroid Build Coastguard Worker struct test_case {
64*49cdfc7eSAndroid Build Coastguard Worker 	char *key;
65*49cdfc7eSAndroid Build Coastguard Worker 	char **value;
66*49cdfc7eSAndroid Build Coastguard Worker 	size_t size;
67*49cdfc7eSAndroid Build Coastguard Worker 	int flags;
68*49cdfc7eSAndroid Build Coastguard Worker 	int exp_err;
69*49cdfc7eSAndroid Build Coastguard Worker 	int keyneeded;
70*49cdfc7eSAndroid Build Coastguard Worker };
71*49cdfc7eSAndroid Build Coastguard Worker 
72*49cdfc7eSAndroid Build Coastguard Worker struct test_case tc[] = {
73*49cdfc7eSAndroid Build Coastguard Worker 	{			/* case 00, invalid flags */
74*49cdfc7eSAndroid Build Coastguard Worker 	 .key = XATTR_TEST_KEY,
75*49cdfc7eSAndroid Build Coastguard Worker 	 .value = &xattr_value,
76*49cdfc7eSAndroid Build Coastguard Worker 	 .size = XATTR_TEST_VALUE_SIZE,
77*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = ~0,
78*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_err = EINVAL,
79*49cdfc7eSAndroid Build Coastguard Worker 	 },
80*49cdfc7eSAndroid Build Coastguard Worker 	{			/* case 01, replace non-existing attribute */
81*49cdfc7eSAndroid Build Coastguard Worker 	 .key = XATTR_TEST_KEY,
82*49cdfc7eSAndroid Build Coastguard Worker 	 .value = &xattr_value,
83*49cdfc7eSAndroid Build Coastguard Worker 	 .size = XATTR_TEST_VALUE_SIZE,
84*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = XATTR_REPLACE,
85*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_err = ENODATA,
86*49cdfc7eSAndroid Build Coastguard Worker 	 },
87*49cdfc7eSAndroid Build Coastguard Worker 	{			/* case 02, long key name */
88*49cdfc7eSAndroid Build Coastguard Worker 	 .key = long_key,
89*49cdfc7eSAndroid Build Coastguard Worker 	 .value = &xattr_value,
90*49cdfc7eSAndroid Build Coastguard Worker 	 .size = XATTR_TEST_VALUE_SIZE,
91*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = XATTR_CREATE,
92*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_err = ERANGE,
93*49cdfc7eSAndroid Build Coastguard Worker 	 },
94*49cdfc7eSAndroid Build Coastguard Worker 	{			/* case 03, long value */
95*49cdfc7eSAndroid Build Coastguard Worker 	 .key = XATTR_TEST_KEY,
96*49cdfc7eSAndroid Build Coastguard Worker 	 .value = &long_value,
97*49cdfc7eSAndroid Build Coastguard Worker 	 .size = XATTR_SIZE_MAX + 1,
98*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = XATTR_CREATE,
99*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_err = E2BIG,
100*49cdfc7eSAndroid Build Coastguard Worker 	 },
101*49cdfc7eSAndroid Build Coastguard Worker 	{			/* case 04, zero length value */
102*49cdfc7eSAndroid Build Coastguard Worker 	 .key = XATTR_TEST_KEY,
103*49cdfc7eSAndroid Build Coastguard Worker 	 .value = &xattr_value,
104*49cdfc7eSAndroid Build Coastguard Worker 	 .size = 0,
105*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = XATTR_CREATE,
106*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_err = 0,
107*49cdfc7eSAndroid Build Coastguard Worker 	 },
108*49cdfc7eSAndroid Build Coastguard Worker 	{			/* case 05, create existing attribute */
109*49cdfc7eSAndroid Build Coastguard Worker 	 .key = XATTR_TEST_KEY,
110*49cdfc7eSAndroid Build Coastguard Worker 	 .value = &xattr_value,
111*49cdfc7eSAndroid Build Coastguard Worker 	 .size = XATTR_TEST_VALUE_SIZE,
112*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = XATTR_CREATE,
113*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_err = EEXIST,
114*49cdfc7eSAndroid Build Coastguard Worker 	 .keyneeded = 1,
115*49cdfc7eSAndroid Build Coastguard Worker 	 },
116*49cdfc7eSAndroid Build Coastguard Worker 	{			/* case 06, replace existing attribute */
117*49cdfc7eSAndroid Build Coastguard Worker 	 .key = XATTR_TEST_KEY,
118*49cdfc7eSAndroid Build Coastguard Worker 	 .value = &xattr_value,
119*49cdfc7eSAndroid Build Coastguard Worker 	 .size = XATTR_TEST_VALUE_SIZE,
120*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = XATTR_REPLACE,
121*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_err = 0,
122*49cdfc7eSAndroid Build Coastguard Worker 	 .keyneeded = 1,
123*49cdfc7eSAndroid Build Coastguard Worker 	},
124*49cdfc7eSAndroid Build Coastguard Worker 	{			/* case 07, zero length key */
125*49cdfc7eSAndroid Build Coastguard Worker 	 .key = "",
126*49cdfc7eSAndroid Build Coastguard Worker 	 .value = &xattr_value,
127*49cdfc7eSAndroid Build Coastguard Worker 	 .size = XATTR_TEST_VALUE_SIZE,
128*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = XATTR_CREATE,
129*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_err = ERANGE,
130*49cdfc7eSAndroid Build Coastguard Worker 	},
131*49cdfc7eSAndroid Build Coastguard Worker 	{			/* case 08, NULL key */
132*49cdfc7eSAndroid Build Coastguard Worker 	 .value = &xattr_value,
133*49cdfc7eSAndroid Build Coastguard Worker 	 .size = XATTR_TEST_VALUE_SIZE,
134*49cdfc7eSAndroid Build Coastguard Worker 	 .flags = XATTR_CREATE,
135*49cdfc7eSAndroid Build Coastguard Worker 	 .exp_err = EFAULT,
136*49cdfc7eSAndroid Build Coastguard Worker 	},
137*49cdfc7eSAndroid Build Coastguard Worker };
138*49cdfc7eSAndroid Build Coastguard Worker 
verify_fsetxattr(unsigned int i)139*49cdfc7eSAndroid Build Coastguard Worker static void verify_fsetxattr(unsigned int i)
140*49cdfc7eSAndroid Build Coastguard Worker {
141*49cdfc7eSAndroid Build Coastguard Worker 	/* some tests might require existing keys for each iteration */
142*49cdfc7eSAndroid Build Coastguard Worker 	if (tc[i].keyneeded) {
143*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_FSETXATTR(fd, tc[i].key, *tc[i].value, tc[i].size,
144*49cdfc7eSAndroid Build Coastguard Worker 				XATTR_CREATE);
145*49cdfc7eSAndroid Build Coastguard Worker 	}
146*49cdfc7eSAndroid Build Coastguard Worker 
147*49cdfc7eSAndroid Build Coastguard Worker 	TEST(fsetxattr(fd, tc[i].key, *tc[i].value, tc[i].size, tc[i].flags));
148*49cdfc7eSAndroid Build Coastguard Worker 
149*49cdfc7eSAndroid Build Coastguard Worker 	if (TST_RET == -1 && TST_ERR == EOPNOTSUPP)
150*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TCONF, "fsetxattr(2) not supported");
151*49cdfc7eSAndroid Build Coastguard Worker 
152*49cdfc7eSAndroid Build Coastguard Worker 	/* success */
153*49cdfc7eSAndroid Build Coastguard Worker 
154*49cdfc7eSAndroid Build Coastguard Worker 	if (!tc[i].exp_err) {
155*49cdfc7eSAndroid Build Coastguard Worker 		if (TST_RET) {
156*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL | TTERRNO,
157*49cdfc7eSAndroid Build Coastguard Worker 				"fsetxattr(2) failed with %li", TST_RET);
158*49cdfc7eSAndroid Build Coastguard Worker 			return;
159*49cdfc7eSAndroid Build Coastguard Worker 		}
160*49cdfc7eSAndroid Build Coastguard Worker 
161*49cdfc7eSAndroid Build Coastguard Worker 		/* this is needed for subsequent iterations */
162*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_FREMOVEXATTR(fd, tc[i].key);
163*49cdfc7eSAndroid Build Coastguard Worker 
164*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TPASS, "fsetxattr(2) passed");
165*49cdfc7eSAndroid Build Coastguard Worker 
166*49cdfc7eSAndroid Build Coastguard Worker 		return;
167*49cdfc7eSAndroid Build Coastguard Worker 	}
168*49cdfc7eSAndroid Build Coastguard Worker 
169*49cdfc7eSAndroid Build Coastguard Worker 	if (TST_RET == 0) {
170*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "fsetxattr(2) passed unexpectedly");
171*49cdfc7eSAndroid Build Coastguard Worker 		return;
172*49cdfc7eSAndroid Build Coastguard Worker 	}
173*49cdfc7eSAndroid Build Coastguard Worker 
174*49cdfc7eSAndroid Build Coastguard Worker 	/* error */
175*49cdfc7eSAndroid Build Coastguard Worker 
176*49cdfc7eSAndroid Build Coastguard Worker 	if (tc[i].exp_err != TST_ERR) {
177*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL | TTERRNO, "fsetxattr(2) should fail with %s",
178*49cdfc7eSAndroid Build Coastguard Worker 			tst_strerrno(tc[i].exp_err));
179*49cdfc7eSAndroid Build Coastguard Worker 		return;
180*49cdfc7eSAndroid Build Coastguard Worker 	}
181*49cdfc7eSAndroid Build Coastguard Worker 
182*49cdfc7eSAndroid Build Coastguard Worker 	/* key might have been added AND test might have failed, remove it */
183*49cdfc7eSAndroid Build Coastguard Worker 	if (tc[i].keyneeded)
184*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_FREMOVEXATTR(fd, tc[i].key);
185*49cdfc7eSAndroid Build Coastguard Worker 
186*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TPASS | TTERRNO, "fsetxattr(2) failed");
187*49cdfc7eSAndroid Build Coastguard Worker }
188*49cdfc7eSAndroid Build Coastguard Worker 
cleanup(void)189*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
190*49cdfc7eSAndroid Build Coastguard Worker {
191*49cdfc7eSAndroid Build Coastguard Worker 	if (fd > 0)
192*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_CLOSE(fd);
193*49cdfc7eSAndroid Build Coastguard Worker }
194*49cdfc7eSAndroid Build Coastguard Worker 
setup(void)195*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
196*49cdfc7eSAndroid Build Coastguard Worker {
197*49cdfc7eSAndroid Build Coastguard Worker 	size_t i = 0;
198*49cdfc7eSAndroid Build Coastguard Worker 
199*49cdfc7eSAndroid Build Coastguard Worker 	snprintf(long_key, 6, "%s", "user.");
200*49cdfc7eSAndroid Build Coastguard Worker 	memset(long_key + 5, 'k', XATTR_NAME_LEN - 5);
201*49cdfc7eSAndroid Build Coastguard Worker 	long_key[XATTR_NAME_LEN - 1] = '\0';
202*49cdfc7eSAndroid Build Coastguard Worker 
203*49cdfc7eSAndroid Build Coastguard Worker 	long_value = SAFE_MALLOC(XATTR_SIZE_MAX + 2);
204*49cdfc7eSAndroid Build Coastguard Worker 	memset(long_value, 'v', XATTR_SIZE_MAX + 2);
205*49cdfc7eSAndroid Build Coastguard Worker 	long_value[XATTR_SIZE_MAX + 1] = '\0';
206*49cdfc7eSAndroid Build Coastguard Worker 
207*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_TOUCH(FNAME, 0644, NULL);
208*49cdfc7eSAndroid Build Coastguard Worker 	fd = SAFE_OPEN(FNAME, O_RDONLY);
209*49cdfc7eSAndroid Build Coastguard Worker 
210*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(tc); i++) {
211*49cdfc7eSAndroid Build Coastguard Worker 		if (!tc[i].key)
212*49cdfc7eSAndroid Build Coastguard Worker 			tc[i].key = tst_get_bad_addr(cleanup);
213*49cdfc7eSAndroid Build Coastguard Worker 	}
214*49cdfc7eSAndroid Build Coastguard Worker }
215*49cdfc7eSAndroid Build Coastguard Worker 
216*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
217*49cdfc7eSAndroid Build Coastguard Worker 	.setup = setup,
218*49cdfc7eSAndroid Build Coastguard Worker 	.test = verify_fsetxattr,
219*49cdfc7eSAndroid Build Coastguard Worker 	.cleanup = cleanup,
220*49cdfc7eSAndroid Build Coastguard Worker 	.tcnt = ARRAY_SIZE(tc),
221*49cdfc7eSAndroid Build Coastguard Worker 	.mntpoint = MNTPOINT,
222*49cdfc7eSAndroid Build Coastguard Worker 	.mount_device = 1,
223*49cdfc7eSAndroid Build Coastguard Worker 	.all_filesystems = 1,
224*49cdfc7eSAndroid Build Coastguard Worker 	.needs_root = 1,
225*49cdfc7eSAndroid Build Coastguard Worker };
226*49cdfc7eSAndroid Build Coastguard Worker 
227*49cdfc7eSAndroid Build Coastguard Worker #else /* HAVE_SYS_XATTR_H */
228*49cdfc7eSAndroid Build Coastguard Worker TST_TEST_TCONF("<sys/xattr.h> does not exist");
229*49cdfc7eSAndroid Build Coastguard Worker #endif
230