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