1 /*
2 * Copyright (c) 2016 Fujitsu Ltd.
3 * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 * You should have received a copy of the GNU General Public License
14 * alone with this program.
15 */
16 
17 /*
18 * Test Name: llistxattr02
19 *
20 * Description:
21 * 1) llistxattr(2) fails if the size of the list buffer is too small
22 * to hold the result.
23 * 2) llistxattr(2) fails if path is an empty string.
24 * 3) llistxattr(2) fails when attempted to read from a invalid address.
25 *
26 * Expected Result:
27 * 1) llistxattr(2) should return -1 and set errno to ERANGE.
28 * 2) llistxattr(2) should return -1 and set errno to ENOENT.
29 * 3) llistxattr(2) should return -1 and set errno to EFAULT.
30 */
31 
32 #include "config.h"
33 #include <errno.h>
34 #include <sys/types.h>
35 
36 #ifdef HAVE_ATTR_XATTR_H
37 # include <attr/xattr.h>
38 #endif
39 
40 #include "tst_test.h"
41 
42 #ifdef HAVE_ATTR_XATTR_H
43 
44 #define SECURITY_KEY	"security.ltptest"
45 #define VALUE	"test"
46 #define VALUE_SIZE	4
47 
48 static struct test_case {
49 	const char *path;
50 	size_t size;
51 	int exp_err;
52 } tc[] = {
53 	/* test1 */
54 	{"symlink", 1, ERANGE},
55 	/* test2 */
56 	{"", 20, ENOENT},
57 	/* test3 */
58 	{(char *)-1, 20, EFAULT}
59 };
60 
verify_llistxattr(unsigned int n)61 static void verify_llistxattr(unsigned int n)
62 {
63 	struct test_case *t = tc + n;
64 	char buf[t->size];
65 
66 	TEST(llistxattr(t->path, buf, t->size));
67 	if (TEST_RETURN != -1) {
68 		tst_res(TFAIL, "llistxattr() succeeded unexpectedly");
69 	} else {
70 		if (TEST_ERRNO != t->exp_err) {
71 			tst_res(TFAIL | TTERRNO, "llistxattr() failed "
72 				 "unexpectedlly, expected %s",
73 				 tst_strerrno(t->exp_err));
74 		} else {
75 			tst_res(TPASS | TTERRNO,
76 				 "llistxattr() failed as expected");
77 		}
78 	}
79 }
80 
setup(void)81 static void setup(void)
82 {
83 	int n;
84 
85 	SAFE_TOUCH("testfile", 0644, NULL);
86 
87 	SAFE_SYMLINK("testfile", "symlink");
88 
89 	n = lsetxattr("symlink", SECURITY_KEY, VALUE, VALUE_SIZE, XATTR_CREATE);
90 	if (n == -1) {
91 		if (errno == ENOTSUP) {
92 			tst_brk(TCONF, "no xattr support in fs or "
93 				 "mounted without user_xattr option");
94 		} else {
95 			tst_brk(TBROK | TERRNO, "lsetxattr() failed");
96 		}
97 	}
98 }
99 
100 static struct tst_test test = {
101 	.tid = "llistxattr02",
102 	.needs_tmpdir = 1,
103 	.needs_root = 1,
104 	.test = verify_llistxattr,
105 	.tcnt = ARRAY_SIZE(tc),
106 	.setup = setup,
107 };
108 
109 #else /* HAVE_ATTR_XATTR_H */
110 	TST_TEST_TCONF("<attr/xattr.h> does not exist.");
111 #endif
112