150 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */3 4#include <stdlib.h>5#include <sys/types.h>6#include <sys/xattr.h>7#include <linux/fsverity.h>8#include <unistd.h>9#include <test_progs.h>10#include "test_get_xattr.skel.h"11#include "test_fsverity.skel.h"12 13static const char testfile[] = "/tmp/test_progs_fs_kfuncs";14 15static void test_xattr(void)16{17 struct test_get_xattr *skel = NULL;18 int fd = -1, err;19 int v[32];20 21 fd = open(testfile, O_CREAT | O_RDONLY, 0644);22 if (!ASSERT_GE(fd, 0, "create_file"))23 return;24 25 close(fd);26 fd = -1;27 28 err = setxattr(testfile, "user.kfuncs", "hello", sizeof("hello"), 0);29 if (err && errno == EOPNOTSUPP) {30 printf("%s:SKIP:local fs doesn't support xattr (%d)\n"31 "To run this test, make sure /tmp filesystem supports xattr.\n",32 __func__, errno);33 test__skip();34 goto out;35 }36 37 if (!ASSERT_OK(err, "setxattr"))38 goto out;39 40 skel = test_get_xattr__open_and_load();41 if (!ASSERT_OK_PTR(skel, "test_get_xattr__open_and_load"))42 goto out;43 44 skel->bss->monitored_pid = getpid();45 err = test_get_xattr__attach(skel);46 47 if (!ASSERT_OK(err, "test_get_xattr__attach"))48 goto out;49 50 fd = open(testfile, O_RDONLY, 0644);51 if (!ASSERT_GE(fd, 0, "open_file"))52 goto out;53 54 ASSERT_EQ(skel->bss->found_xattr_from_file, 1, "found_xattr_from_file");55 56 /* Trigger security_inode_getxattr */57 err = getxattr(testfile, "user.kfuncs", v, sizeof(v));58 ASSERT_EQ(err, -1, "getxattr_return");59 ASSERT_EQ(errno, EINVAL, "getxattr_errno");60 ASSERT_EQ(skel->bss->found_xattr_from_dentry, 1, "found_xattr_from_dentry");61 62out:63 close(fd);64 test_get_xattr__destroy(skel);65 remove(testfile);66}67 68#ifndef SHA256_DIGEST_SIZE69#define SHA256_DIGEST_SIZE 3270#endif71 72static void test_fsverity(void)73{74 struct fsverity_enable_arg arg = {0};75 struct test_fsverity *skel = NULL;76 struct fsverity_digest *d;77 int fd, err;78 char buffer[4096];79 80 fd = open(testfile, O_CREAT | O_RDWR, 0644);81 if (!ASSERT_GE(fd, 0, "create_file"))82 return;83 84 /* Write random buffer, so the file is not empty */85 err = write(fd, buffer, 4096);86 if (!ASSERT_EQ(err, 4096, "write_file"))87 goto out;88 close(fd);89 90 /* Reopen read-only, otherwise FS_IOC_ENABLE_VERITY will fail */91 fd = open(testfile, O_RDONLY, 0644);92 if (!ASSERT_GE(fd, 0, "open_file1"))93 return;94 95 /* Enable fsverity for the file.96 * If the file system doesn't support verity, this will fail. Skip97 * the test in such case.98 */99 arg.version = 1;100 arg.hash_algorithm = FS_VERITY_HASH_ALG_SHA256;101 arg.block_size = 4096;102 err = ioctl(fd, FS_IOC_ENABLE_VERITY, &arg);103 if (err) {104 printf("%s:SKIP:local fs doesn't support fsverity (%d)\n"105 "To run this test, try enable CONFIG_FS_VERITY and enable FSVerity for the filesystem.\n",106 __func__, errno);107 test__skip();108 goto out;109 }110 111 skel = test_fsverity__open_and_load();112 if (!ASSERT_OK_PTR(skel, "test_fsverity__open_and_load"))113 goto out;114 115 /* Get fsverity_digest from ioctl */116 d = (struct fsverity_digest *)skel->bss->expected_digest;117 d->digest_algorithm = FS_VERITY_HASH_ALG_SHA256;118 d->digest_size = SHA256_DIGEST_SIZE;119 err = ioctl(fd, FS_IOC_MEASURE_VERITY, skel->bss->expected_digest);120 if (!ASSERT_OK(err, "ioctl_FS_IOC_MEASURE_VERITY"))121 goto out;122 123 skel->bss->monitored_pid = getpid();124 err = test_fsverity__attach(skel);125 if (!ASSERT_OK(err, "test_fsverity__attach"))126 goto out;127 128 /* Reopen the file to trigger the program */129 close(fd);130 fd = open(testfile, O_RDONLY);131 if (!ASSERT_GE(fd, 0, "open_file2"))132 goto out;133 134 ASSERT_EQ(skel->bss->got_fsverity, 1, "got_fsverity");135 ASSERT_EQ(skel->bss->digest_matches, 1, "digest_matches");136out:137 close(fd);138 test_fsverity__destroy(skel);139 remove(testfile);140}141 142void test_fs_kfuncs(void)143{144 if (test__start_subtest("xattr"))145 test_xattr();146 147 if (test__start_subtest("fsverity"))148 test_fsverity();149}150