1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
3
4 #include <stdlib.h>
5 #include <sys/types.h>
6 #include <sys/xattr.h>
7 #include <linux/fsverity.h>
8 #include <unistd.h>
9 #include <test_progs.h>
10 #include "test_get_xattr.skel.h"
11 #include "test_fsverity.skel.h"
12
13 static const char testfile[] = "/tmp/test_progs_fs_kfuncs";
14
test_xattr(void)15 static void test_xattr(void)
16 {
17 struct test_get_xattr *skel = NULL;
18 int fd = -1, err;
19 int v[32];
20
21 fd = open(testfile, O_CREAT | O_RDONLY, 0644);
22 if (!ASSERT_GE(fd, 0, "create_file"))
23 return;
24
25 close(fd);
26 fd = -1;
27
28 err = setxattr(testfile, "user.kfuncs", "hello", sizeof("hello"), 0);
29 if (err && errno == EOPNOTSUPP) {
30 printf("%s:SKIP:local fs doesn't support xattr (%d)\n"
31 "To run this test, make sure /tmp filesystem supports xattr.\n",
32 __func__, errno);
33 test__skip();
34 goto out;
35 }
36
37 if (!ASSERT_OK(err, "setxattr"))
38 goto out;
39
40 skel = test_get_xattr__open_and_load();
41 if (!ASSERT_OK_PTR(skel, "test_get_xattr__open_and_load"))
42 goto out;
43
44 skel->bss->monitored_pid = getpid();
45 err = test_get_xattr__attach(skel);
46
47 if (!ASSERT_OK(err, "test_get_xattr__attach"))
48 goto out;
49
50 fd = open(testfile, O_RDONLY, 0644);
51 if (!ASSERT_GE(fd, 0, "open_file"))
52 goto out;
53
54 ASSERT_EQ(skel->bss->found_xattr_from_file, 1, "found_xattr_from_file");
55
56 /* Trigger security_inode_getxattr */
57 err = getxattr(testfile, "user.kfuncs", v, sizeof(v));
58 ASSERT_EQ(err, -1, "getxattr_return");
59 ASSERT_EQ(errno, EINVAL, "getxattr_errno");
60 ASSERT_EQ(skel->bss->found_xattr_from_dentry, 1, "found_xattr_from_dentry");
61
62 out:
63 close(fd);
64 test_get_xattr__destroy(skel);
65 remove(testfile);
66 }
67
68 #ifndef SHA256_DIGEST_SIZE
69 #define SHA256_DIGEST_SIZE 32
70 #endif
71
test_fsverity(void)72 static void test_fsverity(void)
73 {
74 struct fsverity_enable_arg arg = {0};
75 struct test_fsverity *skel = NULL;
76 struct fsverity_digest *d;
77 int fd, err;
78 char buffer[4096];
79
80 fd = open(testfile, O_CREAT | O_RDWR, 0644);
81 if (!ASSERT_GE(fd, 0, "create_file"))
82 return;
83
84 /* Write random buffer, so the file is not empty */
85 err = write(fd, buffer, 4096);
86 if (!ASSERT_EQ(err, 4096, "write_file"))
87 goto out;
88 close(fd);
89
90 /* Reopen read-only, otherwise FS_IOC_ENABLE_VERITY will fail */
91 fd = open(testfile, O_RDONLY, 0644);
92 if (!ASSERT_GE(fd, 0, "open_file1"))
93 return;
94
95 /* Enable fsverity for the file.
96 * If the file system doesn't support verity, this will fail. Skip
97 * the test in such case.
98 */
99 arg.version = 1;
100 arg.hash_algorithm = FS_VERITY_HASH_ALG_SHA256;
101 arg.block_size = 4096;
102 err = ioctl(fd, FS_IOC_ENABLE_VERITY, &arg);
103 if (err) {
104 printf("%s:SKIP:local fs doesn't support fsverity (%d)\n"
105 "To run this test, try enable CONFIG_FS_VERITY and enable FSVerity for the filesystem.\n",
106 __func__, errno);
107 test__skip();
108 goto out;
109 }
110
111 skel = test_fsverity__open_and_load();
112 if (!ASSERT_OK_PTR(skel, "test_fsverity__open_and_load"))
113 goto out;
114
115 /* Get fsverity_digest from ioctl */
116 d = (struct fsverity_digest *)skel->bss->expected_digest;
117 d->digest_algorithm = FS_VERITY_HASH_ALG_SHA256;
118 d->digest_size = SHA256_DIGEST_SIZE;
119 err = ioctl(fd, FS_IOC_MEASURE_VERITY, skel->bss->expected_digest);
120 if (!ASSERT_OK(err, "ioctl_FS_IOC_MEASURE_VERITY"))
121 goto out;
122
123 skel->bss->monitored_pid = getpid();
124 err = test_fsverity__attach(skel);
125 if (!ASSERT_OK(err, "test_fsverity__attach"))
126 goto out;
127
128 /* Reopen the file to trigger the program */
129 close(fd);
130 fd = open(testfile, O_RDONLY);
131 if (!ASSERT_GE(fd, 0, "open_file2"))
132 goto out;
133
134 ASSERT_EQ(skel->bss->got_fsverity, 1, "got_fsverity");
135 ASSERT_EQ(skel->bss->digest_matches, 1, "digest_matches");
136 out:
137 close(fd);
138 test_fsverity__destroy(skel);
139 remove(testfile);
140 }
141
test_fs_kfuncs(void)142 void test_fs_kfuncs(void)
143 {
144 if (test__start_subtest("xattr"))
145 test_xattr();
146
147 if (test__start_subtest("fsverity"))
148 test_fsverity();
149 }
150