195ae251fSEric Biggers // SPDX-License-Identifier: GPL-2.0 295ae251fSEric Biggers /* 395ae251fSEric Biggers * fs/f2fs/verity.c: fs-verity support for f2fs 495ae251fSEric Biggers * 595ae251fSEric Biggers * Copyright 2019 Google LLC 695ae251fSEric Biggers */ 795ae251fSEric Biggers 895ae251fSEric Biggers /* 995ae251fSEric Biggers * Implementation of fsverity_operations for f2fs. 1095ae251fSEric Biggers * 1195ae251fSEric Biggers * Like ext4, f2fs stores the verity metadata (Merkle tree and 1295ae251fSEric Biggers * fsverity_descriptor) past the end of the file, starting at the first 64K 1395ae251fSEric Biggers * boundary beyond i_size. This approach works because (a) verity files are 1495ae251fSEric Biggers * readonly, and (b) pages fully beyond i_size aren't visible to userspace but 1595ae251fSEric Biggers * can be read/written internally by f2fs with only some relatively small 1695ae251fSEric Biggers * changes to f2fs. Extended attributes cannot be used because (a) f2fs limits 1795ae251fSEric Biggers * the total size of an inode's xattr entries to 4096 bytes, which wouldn't be 1895ae251fSEric Biggers * enough for even a single Merkle tree block, and (b) f2fs encryption doesn't 1995ae251fSEric Biggers * encrypt xattrs, yet the verity metadata *must* be encrypted when the file is 2095ae251fSEric Biggers * because it contains hashes of the plaintext data. 2195ae251fSEric Biggers * 2295ae251fSEric Biggers * Using a 64K boundary rather than a 4K one keeps things ready for 2395ae251fSEric Biggers * architectures with 64K pages, and it doesn't necessarily waste space on-disk 2495ae251fSEric Biggers * since there can be a hole between i_size and the start of the Merkle tree. 2595ae251fSEric Biggers */ 2695ae251fSEric Biggers 2795ae251fSEric Biggers #include <linux/f2fs_fs.h> 2895ae251fSEric Biggers 2995ae251fSEric Biggers #include "f2fs.h" 3095ae251fSEric Biggers #include "xattr.h" 3195ae251fSEric Biggers 328fa41016SJack Qiu #define F2FS_VERIFY_VER (1) 338fa41016SJack Qiu 3495ae251fSEric Biggers static inline loff_t f2fs_verity_metadata_pos(const struct inode *inode) 3595ae251fSEric Biggers { 3695ae251fSEric Biggers return round_up(inode->i_size, 65536); 3795ae251fSEric Biggers } 3895ae251fSEric Biggers 3995ae251fSEric Biggers /* 4095ae251fSEric Biggers * Read some verity metadata from the inode. __vfs_read() can't be used because 4195ae251fSEric Biggers * we need to read beyond i_size. 4295ae251fSEric Biggers */ 4395ae251fSEric Biggers static int pagecache_read(struct inode *inode, void *buf, size_t count, 4495ae251fSEric Biggers loff_t pos) 4595ae251fSEric Biggers { 4695ae251fSEric Biggers while (count) { 4795ae251fSEric Biggers size_t n = min_t(size_t, count, 4895ae251fSEric Biggers PAGE_SIZE - offset_in_page(pos)); 4995ae251fSEric Biggers struct page *page; 5095ae251fSEric Biggers 5195ae251fSEric Biggers page = read_mapping_page(inode->i_mapping, pos >> PAGE_SHIFT, 5295ae251fSEric Biggers NULL); 5395ae251fSEric Biggers if (IS_ERR(page)) 5495ae251fSEric Biggers return PTR_ERR(page); 5595ae251fSEric Biggers 56b87846bdSEric Biggers memcpy_from_page(buf, page, offset_in_page(pos), n); 5795ae251fSEric Biggers 5895ae251fSEric Biggers put_page(page); 5995ae251fSEric Biggers 6095ae251fSEric Biggers buf += n; 6195ae251fSEric Biggers pos += n; 6295ae251fSEric Biggers count -= n; 6395ae251fSEric Biggers } 6495ae251fSEric Biggers return 0; 6595ae251fSEric Biggers } 6695ae251fSEric Biggers 6795ae251fSEric Biggers /* 6895ae251fSEric Biggers * Write some verity metadata to the inode for FS_IOC_ENABLE_VERITY. 6995ae251fSEric Biggers * kernel_write() can't be used because the file descriptor is readonly. 7095ae251fSEric Biggers */ 7195ae251fSEric Biggers static int pagecache_write(struct inode *inode, const void *buf, size_t count, 7295ae251fSEric Biggers loff_t pos) 7395ae251fSEric Biggers { 746e0ee044SMatthew Wilcox (Oracle) struct address_space *mapping = inode->i_mapping; 756e0ee044SMatthew Wilcox (Oracle) const struct address_space_operations *aops = mapping->a_ops; 766e0ee044SMatthew Wilcox (Oracle) 77*d33ebd57SZhiguo Niu if (pos + count > F2FS_BLK_TO_BYTES(max_file_blocks(inode))) 7895ae251fSEric Biggers return -EFBIG; 7995ae251fSEric Biggers 8095ae251fSEric Biggers while (count) { 8195ae251fSEric Biggers size_t n = min_t(size_t, count, 8295ae251fSEric Biggers PAGE_SIZE - offset_in_page(pos)); 831da86618SMatthew Wilcox (Oracle) struct folio *folio; 84b1b98967SAlexander Potapenko void *fsdata = NULL; 8595ae251fSEric Biggers int res; 8695ae251fSEric Biggers 871da86618SMatthew Wilcox (Oracle) res = aops->write_begin(NULL, mapping, pos, n, &folio, &fsdata); 8895ae251fSEric Biggers if (res) 8995ae251fSEric Biggers return res; 9095ae251fSEric Biggers 911da86618SMatthew Wilcox (Oracle) memcpy_to_folio(folio, offset_in_folio(folio, pos), buf, n); 9295ae251fSEric Biggers 931da86618SMatthew Wilcox (Oracle) res = aops->write_end(NULL, mapping, pos, n, n, folio, fsdata); 9495ae251fSEric Biggers if (res < 0) 9595ae251fSEric Biggers return res; 9695ae251fSEric Biggers if (res != n) 9795ae251fSEric Biggers return -EIO; 9895ae251fSEric Biggers 9995ae251fSEric Biggers buf += n; 10095ae251fSEric Biggers pos += n; 10195ae251fSEric Biggers count -= n; 10295ae251fSEric Biggers } 10395ae251fSEric Biggers return 0; 10495ae251fSEric Biggers } 10595ae251fSEric Biggers 10695ae251fSEric Biggers /* 10795ae251fSEric Biggers * Format of f2fs verity xattr. This points to the location of the verity 10895ae251fSEric Biggers * descriptor within the file data rather than containing it directly because 10995ae251fSEric Biggers * the verity descriptor *must* be encrypted when f2fs encryption is used. But, 11095ae251fSEric Biggers * f2fs encryption does not encrypt xattrs. 11195ae251fSEric Biggers */ 11295ae251fSEric Biggers struct fsverity_descriptor_location { 11395ae251fSEric Biggers __le32 version; 11495ae251fSEric Biggers __le32 size; 11595ae251fSEric Biggers __le64 pos; 11695ae251fSEric Biggers }; 11795ae251fSEric Biggers 11895ae251fSEric Biggers static int f2fs_begin_enable_verity(struct file *filp) 11995ae251fSEric Biggers { 12095ae251fSEric Biggers struct inode *inode = file_inode(filp); 12195ae251fSEric Biggers int err; 12295ae251fSEric Biggers 12395ae251fSEric Biggers if (f2fs_verity_in_progress(inode)) 12495ae251fSEric Biggers return -EBUSY; 12595ae251fSEric Biggers 1267bc155feSJaegeuk Kim if (f2fs_is_atomic_file(inode)) 12795ae251fSEric Biggers return -EOPNOTSUPP; 12895ae251fSEric Biggers 12995ae251fSEric Biggers /* 13095ae251fSEric Biggers * Since the file was opened readonly, we have to initialize the quotas 13195ae251fSEric Biggers * here and not rely on ->open() doing it. This must be done before 13295ae251fSEric Biggers * evicting the inline data. 13395ae251fSEric Biggers */ 13410a26878SChao Yu err = f2fs_dquot_initialize(inode); 13595ae251fSEric Biggers if (err) 13695ae251fSEric Biggers return err; 13795ae251fSEric Biggers 13895ae251fSEric Biggers err = f2fs_convert_inline_inode(inode); 13995ae251fSEric Biggers if (err) 14095ae251fSEric Biggers return err; 14195ae251fSEric Biggers 14295ae251fSEric Biggers set_inode_flag(inode, FI_VERITY_IN_PROGRESS); 14395ae251fSEric Biggers return 0; 14495ae251fSEric Biggers } 14595ae251fSEric Biggers 14695ae251fSEric Biggers static int f2fs_end_enable_verity(struct file *filp, const void *desc, 14795ae251fSEric Biggers size_t desc_size, u64 merkle_tree_size) 14895ae251fSEric Biggers { 14995ae251fSEric Biggers struct inode *inode = file_inode(filp); 1503c031542SEric Biggers struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 15195ae251fSEric Biggers u64 desc_pos = f2fs_verity_metadata_pos(inode) + merkle_tree_size; 15295ae251fSEric Biggers struct fsverity_descriptor_location dloc = { 1538fa41016SJack Qiu .version = cpu_to_le32(F2FS_VERIFY_VER), 15495ae251fSEric Biggers .size = cpu_to_le32(desc_size), 15595ae251fSEric Biggers .pos = cpu_to_le64(desc_pos), 15695ae251fSEric Biggers }; 1573c031542SEric Biggers int err = 0, err2 = 0; 15895ae251fSEric Biggers 1593c031542SEric Biggers /* 1603c031542SEric Biggers * If an error already occurred (which fs/verity/ signals by passing 1613c031542SEric Biggers * desc == NULL), then only clean-up is needed. 1623c031542SEric Biggers */ 1633c031542SEric Biggers if (desc == NULL) 1643c031542SEric Biggers goto cleanup; 1653c031542SEric Biggers 1663c031542SEric Biggers /* Append the verity descriptor. */ 16795ae251fSEric Biggers err = pagecache_write(inode, desc, desc_size, desc_pos); 1683c031542SEric Biggers if (err) 1693c031542SEric Biggers goto cleanup; 17095ae251fSEric Biggers 1713c031542SEric Biggers /* 1723c031542SEric Biggers * Write all pages (both data and verity metadata). Note that this must 1733c031542SEric Biggers * happen before clearing FI_VERITY_IN_PROGRESS; otherwise pages beyond 1743c031542SEric Biggers * i_size won't be written properly. For crash consistency, this also 1753c031542SEric Biggers * must happen before the verity inode flag gets persisted. 1763c031542SEric Biggers */ 17795ae251fSEric Biggers err = filemap_write_and_wait(inode->i_mapping); 1783c031542SEric Biggers if (err) 1793c031542SEric Biggers goto cleanup; 18095ae251fSEric Biggers 1813c031542SEric Biggers /* Set the verity xattr. */ 18295ae251fSEric Biggers err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_VERITY, 18395ae251fSEric Biggers F2FS_XATTR_NAME_VERITY, &dloc, sizeof(dloc), 18495ae251fSEric Biggers NULL, XATTR_CREATE); 1853c031542SEric Biggers if (err) 1863c031542SEric Biggers goto cleanup; 1873c031542SEric Biggers 1883c031542SEric Biggers /* Finally, set the verity inode flag. */ 18995ae251fSEric Biggers file_set_verity(inode); 19095ae251fSEric Biggers f2fs_set_inode_flags(inode); 19195ae251fSEric Biggers f2fs_mark_inode_dirty_sync(inode, true); 1923c031542SEric Biggers 1933c031542SEric Biggers clear_inode_flag(inode, FI_VERITY_IN_PROGRESS); 1943c031542SEric Biggers return 0; 1953c031542SEric Biggers 1963c031542SEric Biggers cleanup: 1973c031542SEric Biggers /* 1983c031542SEric Biggers * Verity failed to be enabled, so clean up by truncating any verity 1993c031542SEric Biggers * metadata that was written beyond i_size (both from cache and from 2003c031542SEric Biggers * disk) and clearing FI_VERITY_IN_PROGRESS. 2013c031542SEric Biggers * 2023c031542SEric Biggers * Taking i_gc_rwsem[WRITE] is needed to stop f2fs garbage collection 2033c031542SEric Biggers * from re-instantiating cached pages we are truncating (since unlike 2043c031542SEric Biggers * normal file accesses, garbage collection isn't limited by i_size). 2053c031542SEric Biggers */ 206e4544b63STim Murray f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); 2073c031542SEric Biggers truncate_inode_pages(inode->i_mapping, inode->i_size); 2083c031542SEric Biggers err2 = f2fs_truncate(inode); 2093c031542SEric Biggers if (err2) { 2103c031542SEric Biggers f2fs_err(sbi, "Truncating verity metadata failed (errno=%d)", 2113c031542SEric Biggers err2); 2123c031542SEric Biggers set_sbi_flag(sbi, SBI_NEED_FSCK); 21395ae251fSEric Biggers } 214e4544b63STim Murray f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); 2153c031542SEric Biggers clear_inode_flag(inode, FI_VERITY_IN_PROGRESS); 2163c031542SEric Biggers return err ?: err2; 21795ae251fSEric Biggers } 21895ae251fSEric Biggers 21995ae251fSEric Biggers static int f2fs_get_verity_descriptor(struct inode *inode, void *buf, 22095ae251fSEric Biggers size_t buf_size) 22195ae251fSEric Biggers { 22295ae251fSEric Biggers struct fsverity_descriptor_location dloc; 22395ae251fSEric Biggers int res; 22495ae251fSEric Biggers u32 size; 22595ae251fSEric Biggers u64 pos; 22695ae251fSEric Biggers 22795ae251fSEric Biggers /* Get the descriptor location */ 22895ae251fSEric Biggers res = f2fs_getxattr(inode, F2FS_XATTR_INDEX_VERITY, 22995ae251fSEric Biggers F2FS_XATTR_NAME_VERITY, &dloc, sizeof(dloc), NULL); 23095ae251fSEric Biggers if (res < 0 && res != -ERANGE) 23195ae251fSEric Biggers return res; 2328fa41016SJack Qiu if (res != sizeof(dloc) || dloc.version != cpu_to_le32(F2FS_VERIFY_VER)) { 23395ae251fSEric Biggers f2fs_warn(F2FS_I_SB(inode), "unknown verity xattr format"); 23495ae251fSEric Biggers return -EINVAL; 23595ae251fSEric Biggers } 23695ae251fSEric Biggers size = le32_to_cpu(dloc.size); 23795ae251fSEric Biggers pos = le64_to_cpu(dloc.pos); 23895ae251fSEric Biggers 23995ae251fSEric Biggers /* Get the descriptor */ 240*d33ebd57SZhiguo Niu if (pos + size < pos || 241*d33ebd57SZhiguo Niu pos + size > F2FS_BLK_TO_BYTES(max_file_blocks(inode)) || 24295ae251fSEric Biggers pos < f2fs_verity_metadata_pos(inode) || size > INT_MAX) { 24395ae251fSEric Biggers f2fs_warn(F2FS_I_SB(inode), "invalid verity xattr"); 24495fa90c9SChao Yu f2fs_handle_error(F2FS_I_SB(inode), 24595fa90c9SChao Yu ERROR_CORRUPTED_VERITY_XATTR); 24695ae251fSEric Biggers return -EFSCORRUPTED; 24795ae251fSEric Biggers } 24895ae251fSEric Biggers if (buf_size) { 24995ae251fSEric Biggers if (size > buf_size) 25095ae251fSEric Biggers return -ERANGE; 25195ae251fSEric Biggers res = pagecache_read(inode, buf, size, pos); 25295ae251fSEric Biggers if (res) 25395ae251fSEric Biggers return res; 25495ae251fSEric Biggers } 25595ae251fSEric Biggers return size; 25695ae251fSEric Biggers } 25795ae251fSEric Biggers 258fd39073dSEric Biggers static struct page *f2fs_read_merkle_tree_page(struct inode *inode, 259fd39073dSEric Biggers pgoff_t index, 260fd39073dSEric Biggers unsigned long num_ra_pages) 261fd39073dSEric Biggers { 2621ff61a32SHuangXiaojia struct folio *folio; 263fd39073dSEric Biggers 26495ae251fSEric Biggers index += f2fs_verity_metadata_pos(inode) >> PAGE_SHIFT; 26595ae251fSEric Biggers 2661ff61a32SHuangXiaojia folio = __filemap_get_folio(inode->i_mapping, index, FGP_ACCESSED, 0); 2671ff61a32SHuangXiaojia if (IS_ERR(folio) || !folio_test_uptodate(folio)) { 2684fa0e3ffSMatthew Wilcox (Oracle) DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index); 2694fa0e3ffSMatthew Wilcox (Oracle) 2701ff61a32SHuangXiaojia if (!IS_ERR(folio)) 2711ff61a32SHuangXiaojia folio_put(folio); 272fd39073dSEric Biggers else if (num_ra_pages > 1) 27373bb49daSMatthew Wilcox (Oracle) page_cache_ra_unbounded(&ractl, num_ra_pages, 0); 2741ff61a32SHuangXiaojia folio = read_mapping_folio(inode->i_mapping, index, NULL); 2751ff61a32SHuangXiaojia if (IS_ERR(folio)) 2761ff61a32SHuangXiaojia return ERR_CAST(folio); 277fd39073dSEric Biggers } 2781ff61a32SHuangXiaojia return folio_file_page(folio, index); 27995ae251fSEric Biggers } 28095ae251fSEric Biggers 28195ae251fSEric Biggers static int f2fs_write_merkle_tree_block(struct inode *inode, const void *buf, 28272ea15f0SEric Biggers u64 pos, unsigned int size) 28395ae251fSEric Biggers { 28472ea15f0SEric Biggers pos += f2fs_verity_metadata_pos(inode); 28595ae251fSEric Biggers 28672ea15f0SEric Biggers return pagecache_write(inode, buf, size, pos); 28795ae251fSEric Biggers } 28895ae251fSEric Biggers 28995ae251fSEric Biggers const struct fsverity_operations f2fs_verityops = { 29095ae251fSEric Biggers .begin_enable_verity = f2fs_begin_enable_verity, 29195ae251fSEric Biggers .end_enable_verity = f2fs_end_enable_verity, 29295ae251fSEric Biggers .get_verity_descriptor = f2fs_get_verity_descriptor, 29395ae251fSEric Biggers .read_merkle_tree_page = f2fs_read_merkle_tree_page, 29495ae251fSEric Biggers .write_merkle_tree_block = f2fs_write_merkle_tree_block, 29595ae251fSEric Biggers }; 296