mirror of
https://github.com/raspberrypi/linux.git
synced 2026-01-04 18:27:36 +00:00
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>
167 lines
4.4 KiB
C
167 lines
4.4 KiB
C
// 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_get_xattr(const char *name, const char *value, bool allow_access)
|
|
{
|
|
struct test_get_xattr *skel = NULL;
|
|
int fd = -1, err;
|
|
int v[32];
|
|
|
|
fd = open(testfile, O_CREAT | O_RDONLY, 0644);
|
|
if (!ASSERT_GE(fd, 0, "create_file"))
|
|
return;
|
|
|
|
close(fd);
|
|
fd = -1;
|
|
|
|
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",
|
|
__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;
|
|
|
|
/* Trigger security_inode_getxattr */
|
|
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);
|
|
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)
|
|
{
|
|
/* 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();
|
|
}
|