xref: /linux/tools/testing/selftests/bpf/progs/test_get_xattr.c (revision 4f9786035f9e519db41375818e1d0b5f20da2f10)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
3 
4 #include "vmlinux.h"
5 #include <errno.h>
6 #include <bpf/bpf_helpers.h>
7 #include <bpf/bpf_tracing.h>
8 #include "bpf_kfuncs.h"
9 #include "bpf_misc.h"
10 
11 char _license[] SEC("license") = "GPL";
12 
13 __u32 monitored_pid;
14 __u32 found_xattr_from_file;
15 __u32 found_xattr_from_dentry;
16 
17 static const char expected_value[] = "hello";
18 char value1[32];
19 char value2[32];
20 
21 /* Matches caller of test_get_xattr() in prog_tests/fs_kfuncs.c */
22 static const char xattr_names[][64] = {
23 	/* The following work. */
24 	"user.kfuncs",
25 	"security.bpf.xxx",
26 
27 	/* The following do not work. */
28 	"security.bpf",
29 	"security.selinux"
30 };
31 
32 SEC("lsm.s/file_open")
33 int BPF_PROG(test_file_open, struct file *f)
34 {
35 	struct bpf_dynptr value_ptr;
36 	__u32 pid;
37 	int ret, i;
38 
39 	pid = bpf_get_current_pid_tgid() >> 32;
40 	if (pid != monitored_pid)
41 		return 0;
42 
43 	bpf_dynptr_from_mem(value1, sizeof(value1), 0, &value_ptr);
44 
45 	for (i = 0; i < ARRAY_SIZE(xattr_names); i++) {
46 		ret = bpf_get_file_xattr(f, xattr_names[i], &value_ptr);
47 		if (ret == sizeof(expected_value))
48 			break;
49 	}
50 	if (ret != sizeof(expected_value))
51 		return 0;
52 	if (bpf_strncmp(value1, ret, expected_value))
53 		return 0;
54 	found_xattr_from_file = 1;
55 	return 0;
56 }
57 
58 SEC("lsm.s/inode_getxattr")
59 int BPF_PROG(test_inode_getxattr, struct dentry *dentry, char *name)
60 {
61 	struct bpf_dynptr value_ptr;
62 	__u32 pid;
63 	int ret, i;
64 
65 	pid = bpf_get_current_pid_tgid() >> 32;
66 	if (pid != monitored_pid)
67 		return 0;
68 
69 	bpf_dynptr_from_mem(value2, sizeof(value2), 0, &value_ptr);
70 
71 	for (i = 0; i < ARRAY_SIZE(xattr_names); i++) {
72 		ret = bpf_get_dentry_xattr(dentry, xattr_names[i], &value_ptr);
73 		if (ret == sizeof(expected_value))
74 			break;
75 	}
76 	if (ret != sizeof(expected_value))
77 		return 0;
78 	if (bpf_strncmp(value2, ret, expected_value))
79 		return 0;
80 	found_xattr_from_dentry = 1;
81 
82 	/* return non-zero to fail getxattr from user space */
83 	return -EINVAL;
84 }
85