1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2018 Linaro Limited. All rights reserved.
4f08c3bdfSopenharmony_ci * Author: Rafael David Tinoco <rafael.tinoco@linaro.org>
5f08c3bdfSopenharmony_ci */
6f08c3bdfSopenharmony_ci
7f08c3bdfSopenharmony_ci/*
8f08c3bdfSopenharmony_ci * Test Name: lremovexattr01
9f08c3bdfSopenharmony_ci *
10f08c3bdfSopenharmony_ci * Description:
11f08c3bdfSopenharmony_ci * lremovexattr(2) removes the extended attribute identified by a name and
12f08c3bdfSopenharmony_ci * associated with a given path in the filesystem. Unlike removexattr(2),
13f08c3bdfSopenharmony_ci * lremovexattr(2) removes the attribute from the symbolic link only, and not
14f08c3bdfSopenharmony_ci * the file. This test verifies that a simple call to lremovexattr(2) removes,
15f08c3bdfSopenharmony_ci * indeed, a previously set attribute key/value from a symbolic link, and the
16f08c3bdfSopenharmony_ci * symbolic link _only_.
17f08c3bdfSopenharmony_ci *
18f08c3bdfSopenharmony_ci * Note:
19f08c3bdfSopenharmony_ci * According to attr(5), extended attributes are interpreted differently from
20f08c3bdfSopenharmony_ci * regular files, directories and symbolic links. User attributes are only
21f08c3bdfSopenharmony_ci * allowed for regular files and directories, thus the need of using trusted.*
22f08c3bdfSopenharmony_ci * attributes for this test.
23f08c3bdfSopenharmony_ci */
24f08c3bdfSopenharmony_ci
25f08c3bdfSopenharmony_ci#include "config.h"
26f08c3bdfSopenharmony_ci#include <errno.h>
27f08c3bdfSopenharmony_ci#include <stdlib.h>
28f08c3bdfSopenharmony_ci#include <stdio.h>
29f08c3bdfSopenharmony_ci#include <unistd.h>
30f08c3bdfSopenharmony_ci#include <fcntl.h>
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_ci#ifdef HAVE_SYS_XATTR_H
33f08c3bdfSopenharmony_ci# include <sys/xattr.h>
34f08c3bdfSopenharmony_ci#endif
35f08c3bdfSopenharmony_ci
36f08c3bdfSopenharmony_ci#include "tst_test.h"
37f08c3bdfSopenharmony_ci
38f08c3bdfSopenharmony_ci#ifdef HAVE_SYS_XATTR_H
39f08c3bdfSopenharmony_ci
40f08c3bdfSopenharmony_ci#define ENOATTR ENODATA
41f08c3bdfSopenharmony_ci
42f08c3bdfSopenharmony_ci#define XATTR_KEY		"trusted.key1"
43f08c3bdfSopenharmony_ci#define XATTR_VALUE		"file and link"
44f08c3bdfSopenharmony_ci#define XATTR_VALUE_SIZE	13
45f08c3bdfSopenharmony_ci
46f08c3bdfSopenharmony_ci#define MNTPOINT "mntpoint"
47f08c3bdfSopenharmony_ci#define FILENAME MNTPOINT"/lremovexattr01testfile"
48f08c3bdfSopenharmony_ci#define SYMLINK  MNTPOINT"/lremovexattr01symlink"
49f08c3bdfSopenharmony_ci
50f08c3bdfSopenharmony_cistatic char got_value[XATTR_VALUE_SIZE];
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_cistatic void verify_lremovexattr(void)
53f08c3bdfSopenharmony_ci{
54f08c3bdfSopenharmony_ci	/* set attribute on both: file and symlink */
55f08c3bdfSopenharmony_ci
56f08c3bdfSopenharmony_ci	SAFE_SETXATTR(FILENAME, XATTR_KEY, XATTR_VALUE, XATTR_VALUE_SIZE,
57f08c3bdfSopenharmony_ci			XATTR_CREATE);
58f08c3bdfSopenharmony_ci
59f08c3bdfSopenharmony_ci	SAFE_LSETXATTR(SYMLINK, XATTR_KEY, XATTR_VALUE, XATTR_VALUE_SIZE,
60f08c3bdfSopenharmony_ci			XATTR_CREATE);
61f08c3bdfSopenharmony_ci
62f08c3bdfSopenharmony_ci	/* remove attribute from symlink only */
63f08c3bdfSopenharmony_ci
64f08c3bdfSopenharmony_ci	TEST(lremovexattr(SYMLINK, XATTR_KEY));
65f08c3bdfSopenharmony_ci
66f08c3bdfSopenharmony_ci	if (TST_RET != 0) {
67f08c3bdfSopenharmony_ci		tst_res(TFAIL | TTERRNO, "lremovexattr(2) failed");
68f08c3bdfSopenharmony_ci		return;
69f08c3bdfSopenharmony_ci	}
70f08c3bdfSopenharmony_ci
71f08c3bdfSopenharmony_ci	/* make sure attribute is gone from symlink */
72f08c3bdfSopenharmony_ci
73f08c3bdfSopenharmony_ci	memset(&got_value, 0, XATTR_VALUE_SIZE);
74f08c3bdfSopenharmony_ci
75f08c3bdfSopenharmony_ci	TEST(lgetxattr(SYMLINK, XATTR_KEY, &got_value, XATTR_VALUE_SIZE));
76f08c3bdfSopenharmony_ci
77f08c3bdfSopenharmony_ci	if (TST_RET >= 0) {
78f08c3bdfSopenharmony_ci		tst_res(TFAIL, "lremovexattr(2) did not work");
79f08c3bdfSopenharmony_ci		return;
80f08c3bdfSopenharmony_ci	}
81f08c3bdfSopenharmony_ci
82f08c3bdfSopenharmony_ci	if (TST_ERR != ENOATTR) {
83f08c3bdfSopenharmony_ci		tst_brk(TBROK | TTERRNO, "lgetxattr(2) failed unexpectedly");
84f08c3bdfSopenharmony_ci		return;
85f08c3bdfSopenharmony_ci	}
86f08c3bdfSopenharmony_ci
87f08c3bdfSopenharmony_ci	/* check if file is unchanged, like it should be */
88f08c3bdfSopenharmony_ci
89f08c3bdfSopenharmony_ci	memset(&got_value, 0, XATTR_VALUE_SIZE);
90f08c3bdfSopenharmony_ci
91f08c3bdfSopenharmony_ci	TEST(getxattr(FILENAME, XATTR_KEY, &got_value, XATTR_VALUE_SIZE));
92f08c3bdfSopenharmony_ci
93f08c3bdfSopenharmony_ci	if (TST_RET <= 0) {
94f08c3bdfSopenharmony_ci		tst_res(TFAIL, "lremovexattr(2) deleted file attribute");
95f08c3bdfSopenharmony_ci		return;
96f08c3bdfSopenharmony_ci	}
97f08c3bdfSopenharmony_ci
98f08c3bdfSopenharmony_ci	if (strncmp(got_value, XATTR_VALUE, XATTR_VALUE_SIZE)) {
99f08c3bdfSopenharmony_ci		tst_res(TFAIL, "lremovexattr(2) changed file attribute");
100f08c3bdfSopenharmony_ci		return;
101f08c3bdfSopenharmony_ci	}
102f08c3bdfSopenharmony_ci
103f08c3bdfSopenharmony_ci	/* cleanup file attribute for iteration */
104f08c3bdfSopenharmony_ci
105f08c3bdfSopenharmony_ci	SAFE_REMOVEXATTR(FILENAME, XATTR_KEY);
106f08c3bdfSopenharmony_ci
107f08c3bdfSopenharmony_ci	tst_res(TPASS, "lremovexattr(2) removed attribute as expected");
108f08c3bdfSopenharmony_ci}
109f08c3bdfSopenharmony_ci
110f08c3bdfSopenharmony_cistatic void setup(void)
111f08c3bdfSopenharmony_ci{
112f08c3bdfSopenharmony_ci	SAFE_TOUCH(FILENAME, 0644, NULL);
113f08c3bdfSopenharmony_ci
114f08c3bdfSopenharmony_ci	if (symlink(FILENAME, SYMLINK) < 0)
115f08c3bdfSopenharmony_ci		tst_brk(TCONF, "symlink() not supported");
116f08c3bdfSopenharmony_ci}
117f08c3bdfSopenharmony_ci
118f08c3bdfSopenharmony_cistatic struct tst_test test = {
119f08c3bdfSopenharmony_ci	.setup = setup,
120f08c3bdfSopenharmony_ci	.test_all = verify_lremovexattr,
121f08c3bdfSopenharmony_ci	.mntpoint = MNTPOINT,
122f08c3bdfSopenharmony_ci	.mount_device = 1,
123f08c3bdfSopenharmony_ci	.all_filesystems = 1,
124f08c3bdfSopenharmony_ci	.needs_root = 1,
125f08c3bdfSopenharmony_ci};
126f08c3bdfSopenharmony_ci
127f08c3bdfSopenharmony_ci#else /* HAVE_SYS_XATTR_H */
128f08c3bdfSopenharmony_ciTST_TEST_TCONF("<sys/xattr.h> does not exist");
129f08c3bdfSopenharmony_ci#endif
130