// SPDX-License-Identifier: GPL-2.0 /* * fs/f2fs/verity.c: fs-verity support for f2fs * * Copyright 2019 Google LLC */ /* * Implementation of fsverity_operations for f2fs. * * Like ext4, f2fs stores the verity metadata (Merkle tree and * fsverity_descriptor) past the end of the file, starting at the first 64K * boundary beyond i_size. This approach works because (a) verity files are * readonly, and (b) pages fully beyond i_size aren't visible to userspace but * can be read/written internally by f2fs with only some relatively small * changes to f2fs. Extended attributes cannot be used because (a) f2fs limits * the total size of an inode's xattr entries to 4096 bytes, which wouldn't be * enough for even a single Merkle tree block, and (b) f2fs encryption doesn't * encrypt xattrs, yet the verity metadata *must* be encrypted when the file is * because it contains hashes of the plaintext data. * * Using a 64K boundary rather than a 4K one keeps things ready for * architectures with 64K pages, and it doesn't necessarily waste space on-disk * since there can be a hole between i_size and the start of the Merkle tree. */ #include <linux/f2fs_fs.h> #include "f2fs.h" #include "xattr.h" #define F2FS_VERIFY_VER … static inline loff_t f2fs_verity_metadata_pos(const struct inode *inode) { … } /* * Read some verity metadata from the inode. __vfs_read() can't be used because * we need to read beyond i_size. */ static int pagecache_read(struct inode *inode, void *buf, size_t count, loff_t pos) { … } /* * Write some verity metadata to the inode for FS_IOC_ENABLE_VERITY. * kernel_write() can't be used because the file descriptor is readonly. */ static int pagecache_write(struct inode *inode, const void *buf, size_t count, loff_t pos) { … } /* * Format of f2fs verity xattr. This points to the location of the verity * descriptor within the file data rather than containing it directly because * the verity descriptor *must* be encrypted when f2fs encryption is used. But, * f2fs encryption does not encrypt xattrs. */ struct fsverity_descriptor_location { … }; static int f2fs_begin_enable_verity(struct file *filp) { … } static int f2fs_end_enable_verity(struct file *filp, const void *desc, size_t desc_size, u64 merkle_tree_size) { … } static int f2fs_get_verity_descriptor(struct inode *inode, void *buf, size_t buf_size) { … } static struct page *f2fs_read_merkle_tree_page(struct inode *inode, pgoff_t index, unsigned long num_ra_pages) { … } static int f2fs_write_merkle_tree_block(struct inode *inode, const void *buf, u64 pos, unsigned int size) { … } const struct fsverity_operations f2fs_verityops = …;