From 5c023f6fd1920aac8533ce75c13cefc604366e98 Mon Sep 17 00:00:00 2001 From: Paul Lawrence Date: Mon, 8 Mar 2021 09:32:40 -0800 Subject: [PATCH] ANDROID: Incremental fs: Support STATX_ATTR_VERITY Bug: 181242243 Test: incfs_test passes Signed-off-by: Paul Lawrence Change-Id: Id996e0d5d95c8b42254d1e1e0c1dad9317183a17 --- fs/incfs/vfs.c | 28 ++++++++++++++++++- .../selftests/filesystems/incfs/incfs_test.c | 12 ++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/fs/incfs/vfs.c b/fs/incfs/vfs.c index 72754fadef0d..2446923fce8e 100644 --- a/fs/incfs/vfs.c +++ b/fs/incfs/vfs.c @@ -55,6 +55,9 @@ static void free_inode(struct inode *inode); static void evict_inode(struct inode *inode); static int incfs_setattr(struct dentry *dentry, struct iattr *ia); +static int incfs_getattr(const struct path *path, + struct kstat *stat, u32 request_mask, + unsigned int query_flags); static ssize_t incfs_getxattr(struct dentry *d, const char *name, void *value, size_t size); static ssize_t incfs_setxattr(struct dentry *d, const char *name, @@ -122,7 +125,7 @@ const struct file_operations incfs_file_ops = { const struct inode_operations incfs_file_inode_ops = { .setattr = incfs_setattr, - .getattr = simple_getattr, + .getattr = incfs_getattr, .listxattr = incfs_listxattr }; @@ -1555,6 +1558,29 @@ static int incfs_setattr(struct dentry *dentry, struct iattr *ia) return simple_setattr(dentry, ia); } + +static int incfs_getattr(const struct path *path, + struct kstat *stat, u32 request_mask, + unsigned int query_flags) +{ + struct inode *inode = d_inode(path->dentry); + + if (IS_VERITY(inode)) + stat->attributes |= STATX_ATTR_VERITY; + stat->attributes_mask |= STATX_ATTR_VERITY; + generic_fillattr(inode, stat); + + /* + * TODO: stat->blocks is wrong at this point. It should be number of + * blocks in the backing file. But that information is not (necessarily) + * available yet - incfs_open_dir_file may not have been called. + * Solution is probably to store the backing file block count in an + * xattr whenever it's changed. + */ + + return 0; +} + static ssize_t incfs_getxattr(struct dentry *d, const char *name, void *value, size_t size) { diff --git a/tools/testing/selftests/filesystems/incfs/incfs_test.c b/tools/testing/selftests/filesystems/incfs/incfs_test.c index 54e3284150ab..8c13948569e9 100644 --- a/tools/testing/selftests/filesystems/incfs/incfs_test.c +++ b/tools/testing/selftests/filesystems/incfs/incfs_test.c @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -3804,10 +3805,16 @@ static int enable_verity(const char *mount_dir, struct test_file *file, .digest_size = 32 }; uint64_t flags; + struct statx statxbuf = {}; memcpy(fsverity_signed_digest.magic, "FSVerity", 8); TEST(filename = concat_file_name(mount_dir, file->name), filename); + TESTEQUAL(syscall(__NR_statx, AT_FDCWD, filename, 0, STATX_ALL, + &statxbuf), 0); + TESTEQUAL(statxbuf.stx_attributes_mask & STATX_ATTR_VERITY, + STATX_ATTR_VERITY); + TESTEQUAL(statxbuf.stx_attributes & STATX_ATTR_VERITY, 0); TEST(fd = open(filename, O_RDONLY | O_CLOEXEC), fd != -1); TESTEQUAL(ioctl(fd, FS_IOC_GETFLAGS, &flags), 0); TESTEQUAL(flags & FS_VERITY_FL, 0); @@ -3863,10 +3870,15 @@ static int validate_verity(const char *mount_dir, struct test_file *file) int fd = -1; uint64_t flags; struct fsverity_digest *digest; + struct statx statxbuf = {}; TEST(digest = malloc(sizeof(struct fsverity_digest) + INCFS_MAX_HASH_SIZE), digest != NULL); TEST(filename = concat_file_name(mount_dir, file->name), filename); + TESTEQUAL(syscall(__NR_statx, AT_FDCWD, filename, 0, STATX_ALL, + &statxbuf), 0); + TESTEQUAL(statxbuf.stx_attributes & STATX_ATTR_VERITY, + STATX_ATTR_VERITY); TEST(fd = open(filename, O_RDONLY | O_CLOEXEC), fd != -1); TESTEQUAL(ioctl(fd, FS_IOC_GETFLAGS, &flags), 0); TESTEQUAL(flags & FS_VERITY_FL, FS_VERITY_FL);