1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (C) 2011 Red Hat, Inc.
4 * Copyright (c) Linux Test Project, 2012-2024
5 */
6
7 /*\
8 * [Description]
9 *
10 * Basic tests for getxattr(2) and make sure getxattr(2) handles error
11 * conditions correctly.
12 *
13 * 1. Get an non-existing attribute, getxattr(2) should return -1 and set errno
14 * to ENODATA.
15 * 2. Buffer size is smaller than attribute value size, getxattr(2) should
16 * return -1 and set errno to ERANGE.
17 * 3. Get attribute, getxattr(2) should succeed, and the attribute got by
18 * getxattr(2) should be same as the value we set.
19 */
20
21 #include <stdlib.h>
22 #include "tst_test.h"
23 #include <sys/xattr.h>
24
25 #define XATTR_TEST_NOKEY "user.nosuchkey"
26 #define XATTR_TEST_KEY "user.testkey"
27 #define XATTR_TEST_VALUE "this is a test value"
28 #define XATTR_TEST_VALUE_SIZE 20
29 #define BUFFSIZE 64
30
31 static char filename[BUFSIZ];
32
33 static struct tcase {
34 char *key;
35 char *value;
36 size_t size;
37 int exp_err;
38 } tcases[] = {
39 { .key = XATTR_TEST_NOKEY, .size = BUFFSIZE - 1, .exp_err = ENODATA },
40 { .key = XATTR_TEST_KEY, .size = 1, .exp_err = ERANGE },
41 { .key = XATTR_TEST_KEY, .size = BUFFSIZE - 1 },
42 };
43
run(unsigned int n)44 static void run(unsigned int n)
45 {
46 struct tcase *tc = &tcases[n];
47
48 if (tc->exp_err) {
49 TST_EXP_FAIL(getxattr(filename, tc->key, tc->value, tc->size),
50 tc->exp_err);
51 return;
52 }
53
54 TST_EXP_VAL(getxattr(filename, tc->key, tc->value, tc->size),
55 XATTR_TEST_VALUE_SIZE);
56
57 if (memcmp(tc->value, XATTR_TEST_VALUE, XATTR_TEST_VALUE_SIZE))
58 tst_res(TFAIL, "Wrong value, expect '%s' got '%s'",
59 XATTR_TEST_VALUE, tc->value);
60 else
61 tst_res(TPASS, "getxattr() retrieved expected value");
62 }
63
setup(void)64 static void setup(void)
65 {
66 int fd;
67 unsigned int i;
68
69 /* Create test file and setup initial xattr */
70 snprintf(filename, BUFSIZ, "getxattr01testfile");
71 fd = SAFE_CREAT(filename, 0644);
72 SAFE_CLOSE(fd);
73
74 SAFE_SETXATTR(filename, XATTR_TEST_KEY, XATTR_TEST_VALUE,
75 strlen(XATTR_TEST_VALUE), XATTR_CREATE);
76
77 for (i = 0; i < ARRAY_SIZE(tcases); i++)
78 tcases[i].value = SAFE_MALLOC(BUFFSIZE);
79 }
80
cleanup(void)81 static void cleanup(void)
82 {
83 unsigned int i;
84
85 for (i = 0; i < ARRAY_SIZE(tcases); i++)
86 free(tcases[i].value);
87 }
88
89 static struct tst_test test = {
90 .needs_tmpdir = 1,
91 .needs_root = 1,
92 .setup = setup,
93 .cleanup = cleanup,
94 .tcnt = ARRAY_SIZE(tcases),
95 .test = run,
96 };
97