1/*
2* Copyright (c) 2016 Fujitsu Ltd.
3* Author: Jinbao Huang <huangjb.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/*
19* Test Name: lgetxattr02
20*
21* Description:
22* 1) lgetxattr(2) fails if the named attribute does not exist.
23* 2) lgetxattr(2) fails if the size of the value buffer is too small
24*    to hold the result.
25* 3) lgetxattr(2) fails when attemptes to read from a invalid address.
26*
27* Expected Result:
28* 1) lgetxattr(2) should return -1 and set errno to ENODATA.
29* 2) lgetxattr(2) should return -1 and set errno to ERANGE.
30* 3) lgetxattr(2) should return -1 and set errno to EFAULT.
31*/
32
33#include "config.h"
34#include <errno.h>
35#include <sys/types.h>
36#include <string.h>
37
38#ifdef HAVE_SYS_XATTR_H
39# include <sys/xattr.h>
40#endif
41
42#include "tst_test.h"
43
44#ifdef HAVE_SYS_XATTR_H
45
46#define SECURITY_KEY	"security.ltptest"
47#define VALUE	"this is a test value"
48
49static struct test_case {
50	const char *path;
51	size_t size;
52	int exp_err;
53} tcase[] = {
54	{"testfile", sizeof(VALUE), ENODATA},
55	{"symlink", 1, ERANGE},
56	{(char *)-1, sizeof(VALUE), EFAULT}
57};
58
59static void verify_lgetxattr(unsigned int n)
60{
61	struct test_case *tc = tcase + n;
62	char buf[tc->size];
63
64	TEST(lgetxattr(tc->path, SECURITY_KEY, buf, sizeof(buf)));
65	if (TEST_RETURN != -1) {
66		tst_res(TFAIL, "lgetxattr() succeeded unexpectedly");
67		return;
68	}
69
70	if (TEST_ERRNO != tc->exp_err) {
71		tst_res(TFAIL | TTERRNO, "lgetxattr() failed unexpectedlly, "
72			"expected %s", tst_strerrno(tc->exp_err));
73	} else {
74		tst_res(TPASS | TTERRNO, "lgetxattr() failed as expected");
75	}
76}
77
78static void setup(void)
79{
80	int res;
81
82	SAFE_TOUCH("testfile", 0644, NULL);
83	SAFE_SYMLINK("testfile", "symlink");
84
85	res = lsetxattr("symlink", SECURITY_KEY, VALUE, strlen(VALUE), XATTR_CREATE);
86	if (res == -1) {
87		if (errno == ENOTSUP) {
88			tst_brk(TCONF, "no xattr support in fs or "
89				"mounted without user_xattr option");
90		} else {
91			tst_brk(TBROK | TERRNO, "lsetxattr(%s) failed",
92				SECURITY_KEY);
93		}
94	}
95}
96
97static struct tst_test test = {
98	.needs_tmpdir = 1,
99	.needs_root = 1,
100	.test = verify_lgetxattr,
101	.tcnt = ARRAY_SIZE(tcase),
102	.setup = setup
103};
104
105#else /* HAVE_SYS_XATTR_H */
106	TST_TEST_TCONF("<sys/xattr.h> does not exist.");
107#endif
108