summaryrefslogtreecommitdiffstats
path: root/fs/f2fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-18 19:59:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-18 19:59:14 -0400
commitf60c55a94e1d127186566f06294f2dadd966e9b4 (patch)
tree2d3dbd572c0096d24f87f581194563ff76e07a6e /fs/f2fs
parent734d1ed83e1f9b7bafb650033fb87c657858cf5b (diff)
parent95ae251fe82838b85c6d37e5a1775006e2a42ae0 (diff)
Merge tag 'fsverity-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt
Pull fs-verity support from Eric Biggers: "fs-verity is a filesystem feature that provides Merkle tree based hashing (similar to dm-verity) for individual readonly files, mainly for the purpose of efficient authenticity verification. This pull request includes: (a) The fs/verity/ support layer and documentation. (b) fs-verity support for ext4 and f2fs. Compared to the original fs-verity patchset from last year, the UAPI to enable fs-verity on a file has been greatly simplified. Lots of other things were cleaned up too. fs-verity is planned to be used by two different projects on Android; most of the userspace code is in place already. Another userspace tool ("fsverity-utils"), and xfstests, are also available. e2fsprogs and f2fs-tools already have fs-verity support. Other people have shown interest in using fs-verity too. I've tested this on ext4 and f2fs with xfstests, both the existing tests and the new fs-verity tests. This has also been in linux-next since July 30 with no reported issues except a couple minor ones I found myself and folded in fixes for. Ted and I will be co-maintaining fs-verity" * tag 'fsverity-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt: f2fs: add fs-verity support ext4: update on-disk format documentation for fs-verity ext4: add fs-verity read support ext4: add basic fs-verity support fs-verity: support builtin file signatures fs-verity: add SHA-512 support fs-verity: implement FS_IOC_MEASURE_VERITY ioctl fs-verity: implement FS_IOC_ENABLE_VERITY ioctl fs-verity: add data verification hooks for ->readpages() fs-verity: add the hook for file ->setattr() fs-verity: add the hook for file ->open() fs-verity: add inode and superblock fields fs-verity: add Kconfig and the helper functions for hashing fs: uapi: define verity bit for FS_IOC_GETFLAGS fs-verity: add UAPI header fs-verity: add MAINTAINERS file entry fs-verity: add a documentation file
Diffstat (limited to 'fs/f2fs')
-rw-r--r--fs/f2fs/Makefile1
-rw-r--r--fs/f2fs/data.c75
-rw-r--r--fs/f2fs/f2fs.h20
-rw-r--r--fs/f2fs/file.c43
-rw-r--r--fs/f2fs/inode.c5
-rw-r--r--fs/f2fs/super.c3
-rw-r--r--fs/f2fs/sysfs.c11
-rw-r--r--fs/f2fs/verity.c247
-rw-r--r--fs/f2fs/xattr.h2
9 files changed, 392 insertions, 15 deletions
diff --git a/fs/f2fs/Makefile b/fs/f2fs/Makefile
index 776c4b936504..2aaecc63834f 100644
--- a/fs/f2fs/Makefile
+++ b/fs/f2fs/Makefile
@@ -8,3 +8,4 @@ f2fs-$(CONFIG_F2FS_STAT_FS) += debug.o
8f2fs-$(CONFIG_F2FS_FS_XATTR) += xattr.o 8f2fs-$(CONFIG_F2FS_FS_XATTR) += xattr.o
9f2fs-$(CONFIG_F2FS_FS_POSIX_ACL) += acl.o 9f2fs-$(CONFIG_F2FS_FS_POSIX_ACL) += acl.o
10f2fs-$(CONFIG_F2FS_IO_TRACE) += trace.o 10f2fs-$(CONFIG_F2FS_IO_TRACE) += trace.o
11f2fs-$(CONFIG_FS_VERITY) += verity.o
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index abbf14e9bd72..54cad80acb7d 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -74,6 +74,7 @@ static enum count_type __read_io_type(struct page *page)
74enum bio_post_read_step { 74enum bio_post_read_step {
75 STEP_INITIAL = 0, 75 STEP_INITIAL = 0,
76 STEP_DECRYPT, 76 STEP_DECRYPT,
77 STEP_VERITY,
77}; 78};
78 79
79struct bio_post_read_ctx { 80struct bio_post_read_ctx {
@@ -120,8 +121,23 @@ static void decrypt_work(struct work_struct *work)
120 bio_post_read_processing(ctx); 121 bio_post_read_processing(ctx);
121} 122}
122 123
124static void verity_work(struct work_struct *work)
125{
126 struct bio_post_read_ctx *ctx =
127 container_of(work, struct bio_post_read_ctx, work);
128
129 fsverity_verify_bio(ctx->bio);
130
131 bio_post_read_processing(ctx);
132}
133
123static void bio_post_read_processing(struct bio_post_read_ctx *ctx) 134static void bio_post_read_processing(struct bio_post_read_ctx *ctx)
124{ 135{
136 /*
137 * We use different work queues for decryption and for verity because
138 * verity may require reading metadata pages that need decryption, and
139 * we shouldn't recurse to the same workqueue.
140 */
125 switch (++ctx->cur_step) { 141 switch (++ctx->cur_step) {
126 case STEP_DECRYPT: 142 case STEP_DECRYPT:
127 if (ctx->enabled_steps & (1 << STEP_DECRYPT)) { 143 if (ctx->enabled_steps & (1 << STEP_DECRYPT)) {
@@ -131,6 +147,14 @@ static void bio_post_read_processing(struct bio_post_read_ctx *ctx)
131 } 147 }
132 ctx->cur_step++; 148 ctx->cur_step++;
133 /* fall-through */ 149 /* fall-through */
150 case STEP_VERITY:
151 if (ctx->enabled_steps & (1 << STEP_VERITY)) {
152 INIT_WORK(&ctx->work, verity_work);
153 fsverity_enqueue_verify_work(&ctx->work);
154 return;
155 }
156 ctx->cur_step++;
157 /* fall-through */
134 default: 158 default:
135 __read_end_io(ctx->bio); 159 __read_end_io(ctx->bio);
136 } 160 }
@@ -608,8 +632,15 @@ out:
608 up_write(&io->io_rwsem); 632 up_write(&io->io_rwsem);
609} 633}
610 634
635static inline bool f2fs_need_verity(const struct inode *inode, pgoff_t idx)
636{
637 return fsverity_active(inode) &&
638 idx < DIV_ROUND_UP(inode->i_size, PAGE_SIZE);
639}
640
611static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr, 641static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
612 unsigned nr_pages, unsigned op_flag) 642 unsigned nr_pages, unsigned op_flag,
643 pgoff_t first_idx)
613{ 644{
614 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 645 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
615 struct bio *bio; 646 struct bio *bio;
@@ -625,6 +656,10 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
625 656
626 if (f2fs_encrypted_file(inode)) 657 if (f2fs_encrypted_file(inode))
627 post_read_steps |= 1 << STEP_DECRYPT; 658 post_read_steps |= 1 << STEP_DECRYPT;
659
660 if (f2fs_need_verity(inode, first_idx))
661 post_read_steps |= 1 << STEP_VERITY;
662
628 if (post_read_steps) { 663 if (post_read_steps) {
629 ctx = mempool_alloc(bio_post_read_ctx_pool, GFP_NOFS); 664 ctx = mempool_alloc(bio_post_read_ctx_pool, GFP_NOFS);
630 if (!ctx) { 665 if (!ctx) {
@@ -646,7 +681,7 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,
646 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 681 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
647 struct bio *bio; 682 struct bio *bio;
648 683
649 bio = f2fs_grab_read_bio(inode, blkaddr, 1, 0); 684 bio = f2fs_grab_read_bio(inode, blkaddr, 1, 0, page->index);
650 if (IS_ERR(bio)) 685 if (IS_ERR(bio))
651 return PTR_ERR(bio); 686 return PTR_ERR(bio);
652 687
@@ -1569,6 +1604,15 @@ out:
1569 return ret; 1604 return ret;
1570} 1605}
1571 1606
1607static inline loff_t f2fs_readpage_limit(struct inode *inode)
1608{
1609 if (IS_ENABLED(CONFIG_FS_VERITY) &&
1610 (IS_VERITY(inode) || f2fs_verity_in_progress(inode)))
1611 return inode->i_sb->s_maxbytes;
1612
1613 return i_size_read(inode);
1614}
1615
1572static int f2fs_read_single_page(struct inode *inode, struct page *page, 1616static int f2fs_read_single_page(struct inode *inode, struct page *page,
1573 unsigned nr_pages, 1617 unsigned nr_pages,
1574 struct f2fs_map_blocks *map, 1618 struct f2fs_map_blocks *map,
@@ -1587,7 +1631,7 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
1587 1631
1588 block_in_file = (sector_t)page_index(page); 1632 block_in_file = (sector_t)page_index(page);
1589 last_block = block_in_file + nr_pages; 1633 last_block = block_in_file + nr_pages;
1590 last_block_in_file = (i_size_read(inode) + blocksize - 1) >> 1634 last_block_in_file = (f2fs_readpage_limit(inode) + blocksize - 1) >>
1591 blkbits; 1635 blkbits;
1592 if (last_block > last_block_in_file) 1636 if (last_block > last_block_in_file)
1593 last_block = last_block_in_file; 1637 last_block = last_block_in_file;
@@ -1632,6 +1676,11 @@ got_it:
1632 } else { 1676 } else {
1633zero_out: 1677zero_out:
1634 zero_user_segment(page, 0, PAGE_SIZE); 1678 zero_user_segment(page, 0, PAGE_SIZE);
1679 if (f2fs_need_verity(inode, page->index) &&
1680 !fsverity_verify_page(page)) {
1681 ret = -EIO;
1682 goto out;
1683 }
1635 if (!PageUptodate(page)) 1684 if (!PageUptodate(page))
1636 SetPageUptodate(page); 1685 SetPageUptodate(page);
1637 unlock_page(page); 1686 unlock_page(page);
@@ -1650,7 +1699,7 @@ submit_and_realloc:
1650 } 1699 }
1651 if (bio == NULL) { 1700 if (bio == NULL) {
1652 bio = f2fs_grab_read_bio(inode, block_nr, nr_pages, 1701 bio = f2fs_grab_read_bio(inode, block_nr, nr_pages,
1653 is_readahead ? REQ_RAHEAD : 0); 1702 is_readahead ? REQ_RAHEAD : 0, page->index);
1654 if (IS_ERR(bio)) { 1703 if (IS_ERR(bio)) {
1655 ret = PTR_ERR(bio); 1704 ret = PTR_ERR(bio);
1656 bio = NULL; 1705 bio = NULL;
@@ -2052,7 +2101,7 @@ static int __write_data_page(struct page *page, bool *submitted,
2052 if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) 2101 if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
2053 goto redirty_out; 2102 goto redirty_out;
2054 2103
2055 if (page->index < end_index) 2104 if (page->index < end_index || f2fs_verity_in_progress(inode))
2056 goto write; 2105 goto write;
2057 2106
2058 /* 2107 /*
@@ -2427,7 +2476,8 @@ static void f2fs_write_failed(struct address_space *mapping, loff_t to)
2427 struct inode *inode = mapping->host; 2476 struct inode *inode = mapping->host;
2428 loff_t i_size = i_size_read(inode); 2477 loff_t i_size = i_size_read(inode);
2429 2478
2430 if (to > i_size) { 2479 /* In the fs-verity case, f2fs_end_enable_verity() does the truncate */
2480 if (to > i_size && !f2fs_verity_in_progress(inode)) {
2431 down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); 2481 down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
2432 down_write(&F2FS_I(inode)->i_mmap_sem); 2482 down_write(&F2FS_I(inode)->i_mmap_sem);
2433 2483
@@ -2458,7 +2508,8 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
2458 * the block addresses when there is no need to fill the page. 2508 * the block addresses when there is no need to fill the page.
2459 */ 2509 */
2460 if (!f2fs_has_inline_data(inode) && len == PAGE_SIZE && 2510 if (!f2fs_has_inline_data(inode) && len == PAGE_SIZE &&
2461 !is_inode_flag_set(inode, FI_NO_PREALLOC)) 2511 !is_inode_flag_set(inode, FI_NO_PREALLOC) &&
2512 !f2fs_verity_in_progress(inode))
2462 return 0; 2513 return 0;
2463 2514
2464 /* f2fs_lock_op avoids race between write CP and convert_inline_page */ 2515 /* f2fs_lock_op avoids race between write CP and convert_inline_page */
@@ -2597,7 +2648,8 @@ repeat:
2597 if (len == PAGE_SIZE || PageUptodate(page)) 2648 if (len == PAGE_SIZE || PageUptodate(page))
2598 return 0; 2649 return 0;
2599 2650
2600 if (!(pos & (PAGE_SIZE - 1)) && (pos + len) >= i_size_read(inode)) { 2651 if (!(pos & (PAGE_SIZE - 1)) && (pos + len) >= i_size_read(inode) &&
2652 !f2fs_verity_in_progress(inode)) {
2601 zero_user_segment(page, len, PAGE_SIZE); 2653 zero_user_segment(page, len, PAGE_SIZE);
2602 return 0; 2654 return 0;
2603 } 2655 }
@@ -2660,7 +2712,8 @@ static int f2fs_write_end(struct file *file,
2660 2712
2661 set_page_dirty(page); 2713 set_page_dirty(page);
2662 2714
2663 if (pos + copied > i_size_read(inode)) 2715 if (pos + copied > i_size_read(inode) &&
2716 !f2fs_verity_in_progress(inode))
2664 f2fs_i_size_write(inode, pos + copied); 2717 f2fs_i_size_write(inode, pos + copied);
2665unlock_out: 2718unlock_out:
2666 f2fs_put_page(page, 1); 2719 f2fs_put_page(page, 1);
@@ -3104,7 +3157,9 @@ void f2fs_clear_page_cache_dirty_tag(struct page *page)
3104 3157
3105int __init f2fs_init_post_read_processing(void) 3158int __init f2fs_init_post_read_processing(void)
3106{ 3159{
3107 bio_post_read_ctx_cache = KMEM_CACHE(bio_post_read_ctx, 0); 3160 bio_post_read_ctx_cache =
3161 kmem_cache_create("f2fs_bio_post_read_ctx",
3162 sizeof(struct bio_post_read_ctx), 0, 0, NULL);
3108 if (!bio_post_read_ctx_cache) 3163 if (!bio_post_read_ctx_cache)
3109 goto fail; 3164 goto fail;
3110 bio_post_read_ctx_pool = 3165 bio_post_read_ctx_pool =
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 17382da7f0bd..7c5f121edac5 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -25,6 +25,7 @@
25#include <crypto/hash.h> 25#include <crypto/hash.h>
26 26
27#include <linux/fscrypt.h> 27#include <linux/fscrypt.h>
28#include <linux/fsverity.h>
28 29
29#ifdef CONFIG_F2FS_CHECK_FS 30#ifdef CONFIG_F2FS_CHECK_FS
30#define f2fs_bug_on(sbi, condition) BUG_ON(condition) 31#define f2fs_bug_on(sbi, condition) BUG_ON(condition)
@@ -151,7 +152,7 @@ struct f2fs_mount_info {
151#define F2FS_FEATURE_QUOTA_INO 0x0080 152#define F2FS_FEATURE_QUOTA_INO 0x0080
152#define F2FS_FEATURE_INODE_CRTIME 0x0100 153#define F2FS_FEATURE_INODE_CRTIME 0x0100
153#define F2FS_FEATURE_LOST_FOUND 0x0200 154#define F2FS_FEATURE_LOST_FOUND 0x0200
154#define F2FS_FEATURE_VERITY 0x0400 /* reserved */ 155#define F2FS_FEATURE_VERITY 0x0400
155#define F2FS_FEATURE_SB_CHKSUM 0x0800 156#define F2FS_FEATURE_SB_CHKSUM 0x0800
156 157
157#define __F2FS_HAS_FEATURE(raw_super, mask) \ 158#define __F2FS_HAS_FEATURE(raw_super, mask) \
@@ -630,7 +631,7 @@ enum {
630#define FADVISE_ENC_NAME_BIT 0x08 631#define FADVISE_ENC_NAME_BIT 0x08
631#define FADVISE_KEEP_SIZE_BIT 0x10 632#define FADVISE_KEEP_SIZE_BIT 0x10
632#define FADVISE_HOT_BIT 0x20 633#define FADVISE_HOT_BIT 0x20
633#define FADVISE_VERITY_BIT 0x40 /* reserved */ 634#define FADVISE_VERITY_BIT 0x40
634 635
635#define FADVISE_MODIFIABLE_BITS (FADVISE_COLD_BIT | FADVISE_HOT_BIT) 636#define FADVISE_MODIFIABLE_BITS (FADVISE_COLD_BIT | FADVISE_HOT_BIT)
636 637
@@ -650,6 +651,8 @@ enum {
650#define file_is_hot(inode) is_file(inode, FADVISE_HOT_BIT) 651#define file_is_hot(inode) is_file(inode, FADVISE_HOT_BIT)
651#define file_set_hot(inode) set_file(inode, FADVISE_HOT_BIT) 652#define file_set_hot(inode) set_file(inode, FADVISE_HOT_BIT)
652#define file_clear_hot(inode) clear_file(inode, FADVISE_HOT_BIT) 653#define file_clear_hot(inode) clear_file(inode, FADVISE_HOT_BIT)
654#define file_is_verity(inode) is_file(inode, FADVISE_VERITY_BIT)
655#define file_set_verity(inode) set_file(inode, FADVISE_VERITY_BIT)
653 656
654#define DEF_DIR_LEVEL 0 657#define DEF_DIR_LEVEL 0
655 658
@@ -2412,6 +2415,7 @@ enum {
2412 FI_PROJ_INHERIT, /* indicate file inherits projectid */ 2415 FI_PROJ_INHERIT, /* indicate file inherits projectid */
2413 FI_PIN_FILE, /* indicate file should not be gced */ 2416 FI_PIN_FILE, /* indicate file should not be gced */
2414 FI_ATOMIC_REVOKE_REQUEST, /* request to drop atomic data */ 2417 FI_ATOMIC_REVOKE_REQUEST, /* request to drop atomic data */
2418 FI_VERITY_IN_PROGRESS, /* building fs-verity Merkle tree */
2415}; 2419};
2416 2420
2417static inline void __mark_inode_dirty_flag(struct inode *inode, 2421static inline void __mark_inode_dirty_flag(struct inode *inode,
@@ -2451,6 +2455,12 @@ static inline void clear_inode_flag(struct inode *inode, int flag)
2451 __mark_inode_dirty_flag(inode, flag, false); 2455 __mark_inode_dirty_flag(inode, flag, false);
2452} 2456}
2453 2457
2458static inline bool f2fs_verity_in_progress(struct inode *inode)
2459{
2460 return IS_ENABLED(CONFIG_FS_VERITY) &&
2461 is_inode_flag_set(inode, FI_VERITY_IN_PROGRESS);
2462}
2463
2454static inline void set_acl_inode(struct inode *inode, umode_t mode) 2464static inline void set_acl_inode(struct inode *inode, umode_t mode)
2455{ 2465{
2456 F2FS_I(inode)->i_acl_mode = mode; 2466 F2FS_I(inode)->i_acl_mode = mode;
@@ -3521,6 +3531,9 @@ void f2fs_exit_sysfs(void);
3521int f2fs_register_sysfs(struct f2fs_sb_info *sbi); 3531int f2fs_register_sysfs(struct f2fs_sb_info *sbi);
3522void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi); 3532void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi);
3523 3533
3534/* verity.c */
3535extern const struct fsverity_operations f2fs_verityops;
3536
3524/* 3537/*
3525 * crypto support 3538 * crypto support
3526 */ 3539 */
@@ -3543,7 +3556,7 @@ static inline void f2fs_set_encrypted_inode(struct inode *inode)
3543 */ 3556 */
3544static inline bool f2fs_post_read_required(struct inode *inode) 3557static inline bool f2fs_post_read_required(struct inode *inode)
3545{ 3558{
3546 return f2fs_encrypted_file(inode); 3559 return f2fs_encrypted_file(inode) || fsverity_active(inode);
3547} 3560}
3548 3561
3549#define F2FS_FEATURE_FUNCS(name, flagname) \ 3562#define F2FS_FEATURE_FUNCS(name, flagname) \
@@ -3561,6 +3574,7 @@ F2FS_FEATURE_FUNCS(flexible_inline_xattr, FLEXIBLE_INLINE_XATTR);
3561F2FS_FEATURE_FUNCS(quota_ino, QUOTA_INO); 3574F2FS_FEATURE_FUNCS(quota_ino, QUOTA_INO);
3562F2FS_FEATURE_FUNCS(inode_crtime, INODE_CRTIME); 3575F2FS_FEATURE_FUNCS(inode_crtime, INODE_CRTIME);
3563F2FS_FEATURE_FUNCS(lost_found, LOST_FOUND); 3576F2FS_FEATURE_FUNCS(lost_found, LOST_FOUND);
3577F2FS_FEATURE_FUNCS(verity, VERITY);
3564F2FS_FEATURE_FUNCS(sb_chksum, SB_CHKSUM); 3578F2FS_FEATURE_FUNCS(sb_chksum, SB_CHKSUM);
3565 3579
3566#ifdef CONFIG_BLK_DEV_ZONED 3580#ifdef CONFIG_BLK_DEV_ZONED
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 6a7349f9ac15..39fffc19e00c 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -496,6 +496,10 @@ static int f2fs_file_open(struct inode *inode, struct file *filp)
496 if (err) 496 if (err)
497 return err; 497 return err;
498 498
499 err = fsverity_file_open(inode, filp);
500 if (err)
501 return err;
502
499 filp->f_mode |= FMODE_NOWAIT; 503 filp->f_mode |= FMODE_NOWAIT;
500 504
501 return dquot_file_open(inode, filp); 505 return dquot_file_open(inode, filp);
@@ -778,6 +782,10 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
778 if (err) 782 if (err)
779 return err; 783 return err;
780 784
785 err = fsverity_prepare_setattr(dentry, attr);
786 if (err)
787 return err;
788
781 if (is_quota_modification(inode, attr)) { 789 if (is_quota_modification(inode, attr)) {
782 err = dquot_initialize(inode); 790 err = dquot_initialize(inode);
783 if (err) 791 if (err)
@@ -1705,7 +1713,8 @@ static const struct {
1705 FS_PROJINHERIT_FL | \ 1713 FS_PROJINHERIT_FL | \
1706 FS_ENCRYPT_FL | \ 1714 FS_ENCRYPT_FL | \
1707 FS_INLINE_DATA_FL | \ 1715 FS_INLINE_DATA_FL | \
1708 FS_NOCOW_FL) 1716 FS_NOCOW_FL | \
1717 FS_VERITY_FL)
1709 1718
1710#define F2FS_SETTABLE_FS_FL ( \ 1719#define F2FS_SETTABLE_FS_FL ( \
1711 FS_SYNC_FL | \ 1720 FS_SYNC_FL | \
@@ -1750,6 +1759,8 @@ static int f2fs_ioc_getflags(struct file *filp, unsigned long arg)
1750 1759
1751 if (IS_ENCRYPTED(inode)) 1760 if (IS_ENCRYPTED(inode))
1752 fsflags |= FS_ENCRYPT_FL; 1761 fsflags |= FS_ENCRYPT_FL;
1762 if (IS_VERITY(inode))
1763 fsflags |= FS_VERITY_FL;
1753 if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode)) 1764 if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode))
1754 fsflags |= FS_INLINE_DATA_FL; 1765 fsflags |= FS_INLINE_DATA_FL;
1755 if (is_inode_flag_set(inode, FI_PIN_FILE)) 1766 if (is_inode_flag_set(inode, FI_PIN_FILE))
@@ -3103,6 +3114,30 @@ static int f2fs_ioc_resize_fs(struct file *filp, unsigned long arg)
3103 return ret; 3114 return ret;
3104} 3115}
3105 3116
3117static int f2fs_ioc_enable_verity(struct file *filp, unsigned long arg)
3118{
3119 struct inode *inode = file_inode(filp);
3120
3121 f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
3122
3123 if (!f2fs_sb_has_verity(F2FS_I_SB(inode))) {
3124 f2fs_warn(F2FS_I_SB(inode),
3125 "Can't enable fs-verity on inode %lu: the verity feature is not enabled on this filesystem.\n",
3126 inode->i_ino);
3127 return -EOPNOTSUPP;
3128 }
3129
3130 return fsverity_ioctl_enable(filp, (const void __user *)arg);
3131}
3132
3133static int f2fs_ioc_measure_verity(struct file *filp, unsigned long arg)
3134{
3135 if (!f2fs_sb_has_verity(F2FS_I_SB(file_inode(filp))))
3136 return -EOPNOTSUPP;
3137
3138 return fsverity_ioctl_measure(filp, (void __user *)arg);
3139}
3140
3106long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 3141long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3107{ 3142{
3108 if (unlikely(f2fs_cp_error(F2FS_I_SB(file_inode(filp))))) 3143 if (unlikely(f2fs_cp_error(F2FS_I_SB(file_inode(filp)))))
@@ -3171,6 +3206,10 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3171 return f2fs_ioc_precache_extents(filp, arg); 3206 return f2fs_ioc_precache_extents(filp, arg);
3172 case F2FS_IOC_RESIZE_FS: 3207 case F2FS_IOC_RESIZE_FS:
3173 return f2fs_ioc_resize_fs(filp, arg); 3208 return f2fs_ioc_resize_fs(filp, arg);
3209 case FS_IOC_ENABLE_VERITY:
3210 return f2fs_ioc_enable_verity(filp, arg);
3211 case FS_IOC_MEASURE_VERITY:
3212 return f2fs_ioc_measure_verity(filp, arg);
3174 default: 3213 default:
3175 return -ENOTTY; 3214 return -ENOTTY;
3176 } 3215 }
@@ -3290,6 +3329,8 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3290 case F2FS_IOC_SET_PIN_FILE: 3329 case F2FS_IOC_SET_PIN_FILE:
3291 case F2FS_IOC_PRECACHE_EXTENTS: 3330 case F2FS_IOC_PRECACHE_EXTENTS:
3292 case F2FS_IOC_RESIZE_FS: 3331 case F2FS_IOC_RESIZE_FS:
3332 case FS_IOC_ENABLE_VERITY:
3333 case FS_IOC_MEASURE_VERITY:
3293 break; 3334 break;
3294 default: 3335 default:
3295 return -ENOIOCTLCMD; 3336 return -ENOIOCTLCMD;
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index a33d7a849b2d..06da75d418e0 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -46,9 +46,11 @@ void f2fs_set_inode_flags(struct inode *inode)
46 new_fl |= S_DIRSYNC; 46 new_fl |= S_DIRSYNC;
47 if (file_is_encrypt(inode)) 47 if (file_is_encrypt(inode))
48 new_fl |= S_ENCRYPTED; 48 new_fl |= S_ENCRYPTED;
49 if (file_is_verity(inode))
50 new_fl |= S_VERITY;
49 inode_set_flags(inode, new_fl, 51 inode_set_flags(inode, new_fl,
50 S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC| 52 S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|
51 S_ENCRYPTED); 53 S_ENCRYPTED|S_VERITY);
52} 54}
53 55
54static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri) 56static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri)
@@ -733,6 +735,7 @@ no_delete:
733 } 735 }
734out_clear: 736out_clear:
735 fscrypt_put_encryption_info(inode); 737 fscrypt_put_encryption_info(inode);
738 fsverity_cleanup_inode(inode);
736 clear_inode(inode); 739 clear_inode(inode);
737} 740}
738 741
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index e15bd29bd453..f43befda0e1a 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -3146,6 +3146,9 @@ try_onemore:
3146#ifdef CONFIG_FS_ENCRYPTION 3146#ifdef CONFIG_FS_ENCRYPTION
3147 sb->s_cop = &f2fs_cryptops; 3147 sb->s_cop = &f2fs_cryptops;
3148#endif 3148#endif
3149#ifdef CONFIG_FS_VERITY
3150 sb->s_vop = &f2fs_verityops;
3151#endif
3149 sb->s_xattr = f2fs_xattr_handlers; 3152 sb->s_xattr = f2fs_xattr_handlers;
3150 sb->s_export_op = &f2fs_export_ops; 3153 sb->s_export_op = &f2fs_export_ops;
3151 sb->s_magic = F2FS_SUPER_MAGIC; 3154 sb->s_magic = F2FS_SUPER_MAGIC;
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 3aeacd0aacfd..0cd64f994068 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -131,6 +131,9 @@ static ssize_t features_show(struct f2fs_attr *a,
131 if (f2fs_sb_has_lost_found(sbi)) 131 if (f2fs_sb_has_lost_found(sbi))
132 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", 132 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
133 len ? ", " : "", "lost_found"); 133 len ? ", " : "", "lost_found");
134 if (f2fs_sb_has_verity(sbi))
135 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
136 len ? ", " : "", "verity");
134 if (f2fs_sb_has_sb_chksum(sbi)) 137 if (f2fs_sb_has_sb_chksum(sbi))
135 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", 138 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
136 len ? ", " : "", "sb_checksum"); 139 len ? ", " : "", "sb_checksum");
@@ -364,6 +367,7 @@ enum feat_id {
364 FEAT_QUOTA_INO, 367 FEAT_QUOTA_INO,
365 FEAT_INODE_CRTIME, 368 FEAT_INODE_CRTIME,
366 FEAT_LOST_FOUND, 369 FEAT_LOST_FOUND,
370 FEAT_VERITY,
367 FEAT_SB_CHECKSUM, 371 FEAT_SB_CHECKSUM,
368}; 372};
369 373
@@ -381,6 +385,7 @@ static ssize_t f2fs_feature_show(struct f2fs_attr *a,
381 case FEAT_QUOTA_INO: 385 case FEAT_QUOTA_INO:
382 case FEAT_INODE_CRTIME: 386 case FEAT_INODE_CRTIME:
383 case FEAT_LOST_FOUND: 387 case FEAT_LOST_FOUND:
388 case FEAT_VERITY:
384 case FEAT_SB_CHECKSUM: 389 case FEAT_SB_CHECKSUM:
385 return snprintf(buf, PAGE_SIZE, "supported\n"); 390 return snprintf(buf, PAGE_SIZE, "supported\n");
386 } 391 }
@@ -470,6 +475,9 @@ F2FS_FEATURE_RO_ATTR(flexible_inline_xattr, FEAT_FLEXIBLE_INLINE_XATTR);
470F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO); 475F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO);
471F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME); 476F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME);
472F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND); 477F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND);
478#ifdef CONFIG_FS_VERITY
479F2FS_FEATURE_RO_ATTR(verity, FEAT_VERITY);
480#endif
473F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM); 481F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM);
474 482
475#define ATTR_LIST(name) (&f2fs_attr_##name.attr) 483#define ATTR_LIST(name) (&f2fs_attr_##name.attr)
@@ -534,6 +542,9 @@ static struct attribute *f2fs_feat_attrs[] = {
534 ATTR_LIST(quota_ino), 542 ATTR_LIST(quota_ino),
535 ATTR_LIST(inode_crtime), 543 ATTR_LIST(inode_crtime),
536 ATTR_LIST(lost_found), 544 ATTR_LIST(lost_found),
545#ifdef CONFIG_FS_VERITY
546 ATTR_LIST(verity),
547#endif
537 ATTR_LIST(sb_checksum), 548 ATTR_LIST(sb_checksum),
538 NULL, 549 NULL,
539}; 550};
diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c
new file mode 100644
index 000000000000..a401ef72bc82
--- /dev/null
+++ b/fs/f2fs/verity.c
@@ -0,0 +1,247 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * fs/f2fs/verity.c: fs-verity support for f2fs
4 *
5 * Copyright 2019 Google LLC
6 */
7
8/*
9 * Implementation of fsverity_operations for f2fs.
10 *
11 * Like ext4, f2fs stores the verity metadata (Merkle tree and
12 * fsverity_descriptor) past the end of the file, starting at the first 64K
13 * boundary beyond i_size. This approach works because (a) verity files are
14 * readonly, and (b) pages fully beyond i_size aren't visible to userspace but
15 * can be read/written internally by f2fs with only some relatively small
16 * changes to f2fs. Extended attributes cannot be used because (a) f2fs limits
17 * the total size of an inode's xattr entries to 4096 bytes, which wouldn't be
18 * enough for even a single Merkle tree block, and (b) f2fs encryption doesn't
19 * encrypt xattrs, yet the verity metadata *must* be encrypted when the file is
20 * because it contains hashes of the plaintext data.
21 *
22 * Using a 64K boundary rather than a 4K one keeps things ready for
23 * architectures with 64K pages, and it doesn't necessarily waste space on-disk
24 * since there can be a hole between i_size and the start of the Merkle tree.
25 */
26
27#include <linux/f2fs_fs.h>
28
29#include "f2fs.h"
30#include "xattr.h"
31
32static inline loff_t f2fs_verity_metadata_pos(const struct inode *inode)
33{
34 return round_up(inode->i_size, 65536);
35}
36
37/*
38 * Read some verity metadata from the inode. __vfs_read() can't be used because
39 * we need to read beyond i_size.
40 */
41static int pagecache_read(struct inode *inode, void *buf, size_t count,
42 loff_t pos)
43{
44 while (count) {
45 size_t n = min_t(size_t, count,
46 PAGE_SIZE - offset_in_page(pos));
47 struct page *page;
48 void *addr;
49
50 page = read_mapping_page(inode->i_mapping, pos >> PAGE_SHIFT,
51 NULL);
52 if (IS_ERR(page))
53 return PTR_ERR(page);
54
55 addr = kmap_atomic(page);
56 memcpy(buf, addr + offset_in_page(pos), n);
57 kunmap_atomic(addr);
58
59 put_page(page);
60
61 buf += n;
62 pos += n;
63 count -= n;
64 }
65 return 0;
66}
67
68/*
69 * Write some verity metadata to the inode for FS_IOC_ENABLE_VERITY.
70 * kernel_write() can't be used because the file descriptor is readonly.
71 */
72static int pagecache_write(struct inode *inode, const void *buf, size_t count,
73 loff_t pos)
74{
75 if (pos + count > inode->i_sb->s_maxbytes)
76 return -EFBIG;
77
78 while (count) {
79 size_t n = min_t(size_t, count,
80 PAGE_SIZE - offset_in_page(pos));
81 struct page *page;
82 void *fsdata;
83 void *addr;
84 int res;
85
86 res = pagecache_write_begin(NULL, inode->i_mapping, pos, n, 0,
87 &page, &fsdata);
88 if (res)
89 return res;
90
91 addr = kmap_atomic(page);
92 memcpy(addr + offset_in_page(pos), buf, n);
93 kunmap_atomic(addr);
94
95 res = pagecache_write_end(NULL, inode->i_mapping, pos, n, n,
96 page, fsdata);
97 if (res < 0)
98 return res;
99 if (res != n)
100 return -EIO;
101
102 buf += n;
103 pos += n;
104 count -= n;
105 }
106 return 0;
107}
108
109/*
110 * Format of f2fs verity xattr. This points to the location of the verity
111 * descriptor within the file data rather than containing it directly because
112 * the verity descriptor *must* be encrypted when f2fs encryption is used. But,
113 * f2fs encryption does not encrypt xattrs.
114 */
115struct fsverity_descriptor_location {
116 __le32 version;
117 __le32 size;
118 __le64 pos;
119};
120
121static int f2fs_begin_enable_verity(struct file *filp)
122{
123 struct inode *inode = file_inode(filp);
124 int err;
125
126 if (f2fs_verity_in_progress(inode))
127 return -EBUSY;
128
129 if (f2fs_is_atomic_file(inode) || f2fs_is_volatile_file(inode))
130 return -EOPNOTSUPP;
131
132 /*
133 * Since the file was opened readonly, we have to initialize the quotas
134 * here and not rely on ->open() doing it. This must be done before
135 * evicting the inline data.
136 */
137 err = dquot_initialize(inode);
138 if (err)
139 return err;
140
141 err = f2fs_convert_inline_inode(inode);
142 if (err)
143 return err;
144
145 set_inode_flag(inode, FI_VERITY_IN_PROGRESS);
146 return 0;
147}
148
149static int f2fs_end_enable_verity(struct file *filp, const void *desc,
150 size_t desc_size, u64 merkle_tree_size)
151{
152 struct inode *inode = file_inode(filp);
153 u64 desc_pos = f2fs_verity_metadata_pos(inode) + merkle_tree_size;
154 struct fsverity_descriptor_location dloc = {
155 .version = cpu_to_le32(1),
156 .size = cpu_to_le32(desc_size),
157 .pos = cpu_to_le64(desc_pos),
158 };
159 int err = 0;
160
161 if (desc != NULL) {
162 /* Succeeded; write the verity descriptor. */
163 err = pagecache_write(inode, desc, desc_size, desc_pos);
164
165 /* Write all pages before clearing FI_VERITY_IN_PROGRESS. */
166 if (!err)
167 err = filemap_write_and_wait(inode->i_mapping);
168 }
169
170 /* If we failed, truncate anything we wrote past i_size. */
171 if (desc == NULL || err)
172 f2fs_truncate(inode);
173
174 clear_inode_flag(inode, FI_VERITY_IN_PROGRESS);
175
176 if (desc != NULL && !err) {
177 err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_VERITY,
178 F2FS_XATTR_NAME_VERITY, &dloc, sizeof(dloc),
179 NULL, XATTR_CREATE);
180 if (!err) {
181 file_set_verity(inode);
182 f2fs_set_inode_flags(inode);
183 f2fs_mark_inode_dirty_sync(inode, true);
184 }
185 }
186 return err;
187}
188
189static int f2fs_get_verity_descriptor(struct inode *inode, void *buf,
190 size_t buf_size)
191{
192 struct fsverity_descriptor_location dloc;
193 int res;
194 u32 size;
195 u64 pos;
196
197 /* Get the descriptor location */
198 res = f2fs_getxattr(inode, F2FS_XATTR_INDEX_VERITY,
199 F2FS_XATTR_NAME_VERITY, &dloc, sizeof(dloc), NULL);
200 if (res < 0 && res != -ERANGE)
201 return res;
202 if (res != sizeof(dloc) || dloc.version != cpu_to_le32(1)) {
203 f2fs_warn(F2FS_I_SB(inode), "unknown verity xattr format");
204 return -EINVAL;
205 }
206 size = le32_to_cpu(dloc.size);
207 pos = le64_to_cpu(dloc.pos);
208
209 /* Get the descriptor */
210 if (pos + size < pos || pos + size > inode->i_sb->s_maxbytes ||
211 pos < f2fs_verity_metadata_pos(inode) || size > INT_MAX) {
212 f2fs_warn(F2FS_I_SB(inode), "invalid verity xattr");
213 return -EFSCORRUPTED;
214 }
215 if (buf_size) {
216 if (size > buf_size)
217 return -ERANGE;
218 res = pagecache_read(inode, buf, size, pos);
219 if (res)
220 return res;
221 }
222 return size;
223}
224
225static struct page *f2fs_read_merkle_tree_page(struct inode *inode,
226 pgoff_t index)
227{
228 index += f2fs_verity_metadata_pos(inode) >> PAGE_SHIFT;
229
230 return read_mapping_page(inode->i_mapping, index, NULL);
231}
232
233static int f2fs_write_merkle_tree_block(struct inode *inode, const void *buf,
234 u64 index, int log_blocksize)
235{
236 loff_t pos = f2fs_verity_metadata_pos(inode) + (index << log_blocksize);
237
238 return pagecache_write(inode, buf, 1 << log_blocksize, pos);
239}
240
241const struct fsverity_operations f2fs_verityops = {
242 .begin_enable_verity = f2fs_begin_enable_verity,
243 .end_enable_verity = f2fs_end_enable_verity,
244 .get_verity_descriptor = f2fs_get_verity_descriptor,
245 .read_merkle_tree_page = f2fs_read_merkle_tree_page,
246 .write_merkle_tree_block = f2fs_write_merkle_tree_block,
247};
diff --git a/fs/f2fs/xattr.h b/fs/f2fs/xattr.h
index a90920e2f949..de0c600b9cab 100644
--- a/fs/f2fs/xattr.h
+++ b/fs/f2fs/xattr.h
@@ -34,8 +34,10 @@
34#define F2FS_XATTR_INDEX_ADVISE 7 34#define F2FS_XATTR_INDEX_ADVISE 7
35/* Should be same as EXT4_XATTR_INDEX_ENCRYPTION */ 35/* Should be same as EXT4_XATTR_INDEX_ENCRYPTION */
36#define F2FS_XATTR_INDEX_ENCRYPTION 9 36#define F2FS_XATTR_INDEX_ENCRYPTION 9
37#define F2FS_XATTR_INDEX_VERITY 11
37 38
38#define F2FS_XATTR_NAME_ENCRYPTION_CONTEXT "c" 39#define F2FS_XATTR_NAME_ENCRYPTION_CONTEXT "c"
40#define F2FS_XATTR_NAME_VERITY "v"
39 41
40struct f2fs_xattr_header { 42struct f2fs_xattr_header {
41 __le32 h_magic; /* magic number for identification */ 43 __le32 h_magic; /* magic number for identification */