Commit ab39ad67 authored by Song Liu's avatar Song Liu Committed by Alexei Starovoitov
Browse files

selftests/bpf: Extend test fs_kfuncs to cover security.bpf. xattr names



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: default avatarSong Liu <song@kernel.org>
Link: https://lore.kernel.org/r/20250130213549.3353349-3-song@kernel.org


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 531118f1
Loading
Loading
Loading
Loading
+27 −10
Original line number Diff line number Diff line
@@ -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));
	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 @@ static void test_fsverity(void)

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();
+24 −4
Original line number Diff line number Diff line
@@ -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))