]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests/bpf: Extend test fs_kfuncs to cover security.bpf. xattr names
authorSong Liu <song@kernel.org>
Thu, 30 Jan 2025 21:35:46 +0000 (13:35 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 14 Feb 2025 03:35:31 +0000 (19:35 -0800)
Extend test_progs fs_kfuncs to cover different xattr names. Specifically:
xattr name "user.kfuncs" and "security.bpf.xxx" can be read from BPF
program with kfuncs bpf_get_[file|dentry]_xattr(); while "security.bpf"
and "security.selinux" cannot be read.

Signed-off-by: Song Liu <song@kernel.org>
Link: https://lore.kernel.org/r/20250130213549.3353349-3-song@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/prog_tests/fs_kfuncs.c
tools/testing/selftests/bpf/progs/test_get_xattr.c

index 5a0b51157451dc92e079f8a5a55920a14ba984a4..419f45b5647292da2e231c82590ad7f32013f005 100644 (file)
@@ -12,7 +12,7 @@
 
 static const char testfile[] = "/tmp/test_progs_fs_kfuncs";
 
-static void test_xattr(void)
+static void test_get_xattr(const char *name, const char *value, bool allow_access)
 {
        struct test_get_xattr *skel = NULL;
        int fd = -1, err;
@@ -25,7 +25,7 @@ static void test_xattr(void)
        close(fd);
        fd = -1;
 
-       err = setxattr(testfile, "user.kfuncs", "hello", sizeof("hello"), 0);
+       err = setxattr(testfile, name, value, strlen(value) + 1, 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",
@@ -48,16 +48,23 @@ static void test_xattr(void)
                goto out;
 
        fd = open(testfile, O_RDONLY, 0644);
+
        if (!ASSERT_GE(fd, 0, "open_file"))
                goto out;
 
-       ASSERT_EQ(skel->bss->found_xattr_from_file, 1, "found_xattr_from_file");
-
        /* Trigger security_inode_getxattr */
-       err = getxattr(testfile, "user.kfuncs", v, sizeof(v));
-       ASSERT_EQ(err, -1, "getxattr_return");
-       ASSERT_EQ(errno, EINVAL, "getxattr_errno");
-       ASSERT_EQ(skel->bss->found_xattr_from_dentry, 1, "found_xattr_from_dentry");
+       err = getxattr(testfile, name, v, sizeof(v));
+
+       if (allow_access) {
+               ASSERT_EQ(err, -1, "getxattr_return");
+               ASSERT_EQ(errno, EINVAL, "getxattr_errno");
+               ASSERT_EQ(skel->bss->found_xattr_from_file, 1, "found_xattr_from_file");
+               ASSERT_EQ(skel->bss->found_xattr_from_dentry, 1, "found_xattr_from_dentry");
+       } else {
+               ASSERT_EQ(err, strlen(value) + 1, "getxattr_return");
+               ASSERT_EQ(skel->bss->found_xattr_from_file, 0, "found_xattr_from_file");
+               ASSERT_EQ(skel->bss->found_xattr_from_dentry, 0, "found_xattr_from_dentry");
+       }
 
 out:
        close(fd);
@@ -141,8 +148,18 @@ out:
 
 void test_fs_kfuncs(void)
 {
-       if (test__start_subtest("xattr"))
-               test_xattr();
+       /* Matches xattr_names in progs/test_get_xattr.c */
+       if (test__start_subtest("user_xattr"))
+               test_get_xattr("user.kfuncs", "hello", true);
+
+       if (test__start_subtest("security_bpf_xattr"))
+               test_get_xattr("security.bpf.xxx", "hello", true);
+
+       if (test__start_subtest("security_bpf_xattr_error"))
+               test_get_xattr("security.bpf", "hello", false);
+
+       if (test__start_subtest("security_selinux_xattr_error"))
+               test_get_xattr("security.selinux", "hello", false);
 
        if (test__start_subtest("fsverity"))
                test_fsverity();
index 66e737720f7c6b93762abf09de632bd89d448cbe..54305f4c9f2ddf149ef41849ff3839549c7fb64f 100644 (file)
@@ -6,6 +6,7 @@
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_tracing.h>
 #include "bpf_kfuncs.h"
+#include "bpf_misc.h"
 
 char _license[] SEC("license") = "GPL";
 
@@ -17,12 +18,23 @@ static const char expected_value[] = "hello";
 char value1[32];
 char value2[32];
 
+/* Matches caller of test_get_xattr() in prog_tests/fs_kfuncs.c */
+static const char xattr_names[][64] = {
+       /* The following work. */
+       "user.kfuncs",
+       "security.bpf.xxx",
+
+       /* The following do not work. */
+       "security.bpf",
+       "security.selinux"
+};
+
 SEC("lsm.s/file_open")
 int BPF_PROG(test_file_open, struct file *f)
 {
        struct bpf_dynptr value_ptr;
        __u32 pid;
-       int ret;
+       int ret, i;
 
        pid = bpf_get_current_pid_tgid() >> 32;
        if (pid != monitored_pid)
@@ -30,7 +42,11 @@ int BPF_PROG(test_file_open, struct file *f)
 
        bpf_dynptr_from_mem(value1, sizeof(value1), 0, &value_ptr);
 
-       ret = bpf_get_file_xattr(f, "user.kfuncs", &value_ptr);
+       for (i = 0; i < ARRAY_SIZE(xattr_names); i++) {
+               ret = bpf_get_file_xattr(f, xattr_names[i], &value_ptr);
+               if (ret == sizeof(expected_value))
+                       break;
+       }
        if (ret != sizeof(expected_value))
                return 0;
        if (bpf_strncmp(value1, ret, expected_value))
@@ -44,7 +60,7 @@ int BPF_PROG(test_inode_getxattr, struct dentry *dentry, char *name)
 {
        struct bpf_dynptr value_ptr;
        __u32 pid;
-       int ret;
+       int ret, i;
 
        pid = bpf_get_current_pid_tgid() >> 32;
        if (pid != monitored_pid)
@@ -52,7 +68,11 @@ int BPF_PROG(test_inode_getxattr, struct dentry *dentry, char *name)
 
        bpf_dynptr_from_mem(value2, sizeof(value2), 0, &value_ptr);
 
-       ret = bpf_get_dentry_xattr(dentry, "user.kfuncs", &value_ptr);
+       for (i = 0; i < ARRAY_SIZE(xattr_names); i++) {
+               ret = bpf_get_dentry_xattr(dentry, xattr_names[i], &value_ptr);
+               if (ret == sizeof(expected_value))
+                       break;
+       }
        if (ret != sizeof(expected_value))
                return 0;
        if (bpf_strncmp(value2, ret, expected_value))