summaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/bpf/prog_tests/fs_kfuncs.c
blob: 37056ba738474314397258ed937588dacf3e3f90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */

#include <stdlib.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include <linux/fsverity.h>
#include <unistd.h>
#include <test_progs.h>
#include "test_get_xattr.skel.h"
#include "test_fsverity.skel.h"

static const char testfile[] = "/tmp/test_progs_fs_kfuncs";

static void test_xattr(void)
{
	struct test_get_xattr *skel = NULL;
	int fd = -1, err;

	fd = open(testfile, O_CREAT | O_RDONLY, 0644);
	if (!ASSERT_GE(fd, 0, "create_file"))
		return;

	close(fd);
	fd = -1;

	err = setxattr(testfile, "user.kfuncs", "hello", sizeof("hello"), 0);
	if (err && errno == EOPNOTSUPP) {
		printf("%s:SKIP:local fs doesn't support xattr (%d)\n"
		       "To run this test, make sure /tmp filesystem supports xattr.\n",
		       __func__, errno);
		test__skip();
		goto out;
	}

	if (!ASSERT_OK(err, "setxattr"))
		goto out;

	skel = test_get_xattr__open_and_load();
	if (!ASSERT_OK_PTR(skel, "test_get_xattr__open_and_load"))
		goto out;

	skel->bss->monitored_pid = getpid();
	err = test_get_xattr__attach(skel);

	if (!ASSERT_OK(err, "test_get_xattr__attach"))
		goto out;

	fd = open(testfile, O_RDONLY, 0644);
	if (!ASSERT_GE(fd, 0, "open_file"))
		goto out;

	ASSERT_EQ(skel->bss->found_xattr, 1, "found_xattr");

out:
	close(fd);
	test_get_xattr__destroy(skel);
	remove(testfile);
}

#ifndef SHA256_DIGEST_SIZE
#define SHA256_DIGEST_SIZE      32
#endif

static void test_fsverity(void)
{
	struct fsverity_enable_arg arg = {0};
	struct test_fsverity *skel = NULL;
	struct fsverity_digest *d;
	int fd, err;
	char buffer[4096];

	fd = open(testfile, O_CREAT | O_RDWR, 0644);
	if (!ASSERT_GE(fd, 0, "create_file"))
		return;

	/* Write random buffer, so the file is not empty */
	err = write(fd, buffer, 4096);
	if (!ASSERT_EQ(err, 4096, "write_file"))
		goto out;
	close(fd);

	/* Reopen read-only, otherwise FS_IOC_ENABLE_VERITY will fail */
	fd = open(testfile, O_RDONLY, 0644);
	if (!ASSERT_GE(fd, 0, "open_file1"))
		return;

	/* Enable fsverity for the file.
	 * If the file system doesn't support verity, this will fail. Skip
	 * the test in such case.
	 */
	arg.version = 1;
	arg.hash_algorithm = FS_VERITY_HASH_ALG_SHA256;
	arg.block_size = 4096;
	err = ioctl(fd, FS_IOC_ENABLE_VERITY, &arg);
	if (err) {
		printf("%s:SKIP:local fs doesn't support fsverity (%d)\n"
		       "To run this test, try enable CONFIG_FS_VERITY and enable FSVerity for the filesystem.\n",
		       __func__, errno);
		test__skip();
		goto out;
	}

	skel = test_fsverity__open_and_load();
	if (!ASSERT_OK_PTR(skel, "test_fsverity__open_and_load"))
		goto out;

	/* Get fsverity_digest from ioctl */
	d = (struct fsverity_digest *)skel->bss->expected_digest;
	d->digest_algorithm = FS_VERITY_HASH_ALG_SHA256;
	d->digest_size = SHA256_DIGEST_SIZE;
	err = ioctl(fd, FS_IOC_MEASURE_VERITY, skel->bss->expected_digest);
	if (!ASSERT_OK(err, "ioctl_FS_IOC_MEASURE_VERITY"))
		goto out;

	skel->bss->monitored_pid = getpid();
	err = test_fsverity__attach(skel);
	if (!ASSERT_OK(err, "test_fsverity__attach"))
		goto out;

	/* Reopen the file to trigger the program */
	close(fd);
	fd = open(testfile, O_RDONLY);
	if (!ASSERT_GE(fd, 0, "open_file2"))
		goto out;

	ASSERT_EQ(skel->bss->got_fsverity, 1, "got_fsverity");
	ASSERT_EQ(skel->bss->digest_matches, 1, "digest_matches");
out:
	close(fd);
	test_fsverity__destroy(skel);
	remove(testfile);
}

void test_fs_kfuncs(void)
{
	if (test__start_subtest("xattr"))
		test_xattr();

	if (test__start_subtest("fsverity"))
		test_fsverity();
}