1 // SPDX-License-Identifier: GPL-2.0 2 /* 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 13 static const char testfile[] = "/tmp/test_progs_fs_kfuncs"; 14 15 static void test_xattr(void) 16 { 17 struct test_get_xattr *skel = NULL; 18 int fd = -1, err; 19 20 fd = open(testfile, O_CREAT | O_RDONLY, 0644); 21 if (!ASSERT_GE(fd, 0, "create_file")) 22 return; 23 24 close(fd); 25 fd = -1; 26 27 err = setxattr(testfile, "user.kfuncs", "hello", sizeof("hello"), 0); 28 if (!ASSERT_OK(err, "setxattr")) 29 goto out; 30 31 skel = test_get_xattr__open_and_load(); 32 if (!ASSERT_OK_PTR(skel, "test_get_xattr__open_and_load")) 33 goto out; 34 35 skel->bss->monitored_pid = getpid(); 36 err = test_get_xattr__attach(skel); 37 38 if (!ASSERT_OK(err, "test_get_xattr__attach")) 39 goto out; 40 41 fd = open(testfile, O_RDONLY, 0644); 42 if (!ASSERT_GE(fd, 0, "open_file")) 43 goto out; 44 45 ASSERT_EQ(skel->bss->found_xattr, 1, "found_xattr"); 46 47 out: 48 close(fd); 49 test_get_xattr__destroy(skel); 50 remove(testfile); 51 } 52 53 #ifndef SHA256_DIGEST_SIZE 54 #define SHA256_DIGEST_SIZE 32 55 #endif 56 57 static void test_fsverity(void) 58 { 59 struct fsverity_enable_arg arg = {0}; 60 struct test_fsverity *skel = NULL; 61 struct fsverity_digest *d; 62 int fd, err; 63 char buffer[4096]; 64 65 fd = open(testfile, O_CREAT | O_RDWR, 0644); 66 if (!ASSERT_GE(fd, 0, "create_file")) 67 return; 68 69 /* Write random buffer, so the file is not empty */ 70 err = write(fd, buffer, 4096); 71 if (!ASSERT_EQ(err, 4096, "write_file")) 72 goto out; 73 close(fd); 74 75 /* Reopen read-only, otherwise FS_IOC_ENABLE_VERITY will fail */ 76 fd = open(testfile, O_RDONLY, 0644); 77 if (!ASSERT_GE(fd, 0, "open_file1")) 78 return; 79 80 /* Enable fsverity for the file. 81 * If the file system doesn't support verity, this will fail. Skip 82 * the test in such case. 83 */ 84 arg.version = 1; 85 arg.hash_algorithm = FS_VERITY_HASH_ALG_SHA256; 86 arg.block_size = 4096; 87 err = ioctl(fd, FS_IOC_ENABLE_VERITY, &arg); 88 if (err) { 89 printf("%s:SKIP:local fs doesn't support fsverity (%d)\n" 90 "To run this test, try enable CONFIG_FS_VERITY and enable FSVerity for the filesystem.\n", 91 __func__, errno); 92 test__skip(); 93 goto out; 94 } 95 96 skel = test_fsverity__open_and_load(); 97 if (!ASSERT_OK_PTR(skel, "test_fsverity__open_and_load")) 98 goto out; 99 100 /* Get fsverity_digest from ioctl */ 101 d = (struct fsverity_digest *)skel->bss->expected_digest; 102 d->digest_algorithm = FS_VERITY_HASH_ALG_SHA256; 103 d->digest_size = SHA256_DIGEST_SIZE; 104 err = ioctl(fd, FS_IOC_MEASURE_VERITY, skel->bss->expected_digest); 105 if (!ASSERT_OK(err, "ioctl_FS_IOC_MEASURE_VERITY")) 106 goto out; 107 108 skel->bss->monitored_pid = getpid(); 109 err = test_fsverity__attach(skel); 110 if (!ASSERT_OK(err, "test_fsverity__attach")) 111 goto out; 112 113 /* Reopen the file to trigger the program */ 114 close(fd); 115 fd = open(testfile, O_RDONLY); 116 if (!ASSERT_GE(fd, 0, "open_file2")) 117 goto out; 118 119 ASSERT_EQ(skel->bss->got_fsverity, 1, "got_fsverity"); 120 ASSERT_EQ(skel->bss->digest_matches, 1, "digest_matches"); 121 out: 122 close(fd); 123 test_fsverity__destroy(skel); 124 remove(testfile); 125 } 126 127 void test_fs_kfuncs(void) 128 { 129 if (test__start_subtest("xattr")) 130 test_xattr(); 131 132 if (test__start_subtest("fsverity")) 133 test_fsverity(); 134 } 135