summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/Makefile1
-rw-r--r--fs/ext4/ext4.h21
-rw-r--r--fs/ext4/file.c4
-rw-r--r--fs/ext4/inode.c53
-rw-r--r--fs/ext4/ioctl.c13
-rw-r--r--fs/ext4/super.c9
-rw-r--r--fs/ext4/sysfs.c6
-rw-r--r--fs/ext4/verity.c367
8 files changed, 457 insertions, 17 deletions
diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile
index 8fdfcd3c3e04..b17ddc229ac5 100644
--- a/fs/ext4/Makefile
+++ b/fs/ext4/Makefile
@@ -13,3 +13,4 @@ ext4-y := balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \
13 13
14ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o 14ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o
15ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o 15ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o
16ext4-$(CONFIG_FS_VERITY) += verity.o
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index bf660aa7a9e0..736972f46ea6 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -41,6 +41,7 @@
41#endif 41#endif
42 42
43#include <linux/fscrypt.h> 43#include <linux/fscrypt.h>
44#include <linux/fsverity.h>
44 45
45#include <linux/compiler.h> 46#include <linux/compiler.h>
46 47
@@ -395,6 +396,7 @@ struct flex_groups {
395#define EXT4_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ 396#define EXT4_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
396#define EXT4_HUGE_FILE_FL 0x00040000 /* Set to each huge file */ 397#define EXT4_HUGE_FILE_FL 0x00040000 /* Set to each huge file */
397#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ 398#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
399#define EXT4_VERITY_FL 0x00100000 /* Verity protected inode */
398#define EXT4_EA_INODE_FL 0x00200000 /* Inode used for large EA */ 400#define EXT4_EA_INODE_FL 0x00200000 /* Inode used for large EA */
399#define EXT4_EOFBLOCKS_FL 0x00400000 /* Blocks allocated beyond EOF */ 401#define EXT4_EOFBLOCKS_FL 0x00400000 /* Blocks allocated beyond EOF */
400#define EXT4_INLINE_DATA_FL 0x10000000 /* Inode has inline data. */ 402#define EXT4_INLINE_DATA_FL 0x10000000 /* Inode has inline data. */
@@ -402,7 +404,7 @@ struct flex_groups {
402#define EXT4_CASEFOLD_FL 0x40000000 /* Casefolded file */ 404#define EXT4_CASEFOLD_FL 0x40000000 /* Casefolded file */
403#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */ 405#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
404 406
405#define EXT4_FL_USER_VISIBLE 0x704BDFFF /* User visible flags */ 407#define EXT4_FL_USER_VISIBLE 0x705BDFFF /* User visible flags */
406#define EXT4_FL_USER_MODIFIABLE 0x604BC0FF /* User modifiable flags */ 408#define EXT4_FL_USER_MODIFIABLE 0x604BC0FF /* User modifiable flags */
407 409
408/* Flags we can manipulate with through EXT4_IOC_FSSETXATTR */ 410/* Flags we can manipulate with through EXT4_IOC_FSSETXATTR */
@@ -467,6 +469,7 @@ enum {
467 EXT4_INODE_TOPDIR = 17, /* Top of directory hierarchies*/ 469 EXT4_INODE_TOPDIR = 17, /* Top of directory hierarchies*/
468 EXT4_INODE_HUGE_FILE = 18, /* Set to each huge file */ 470 EXT4_INODE_HUGE_FILE = 18, /* Set to each huge file */
469 EXT4_INODE_EXTENTS = 19, /* Inode uses extents */ 471 EXT4_INODE_EXTENTS = 19, /* Inode uses extents */
472 EXT4_INODE_VERITY = 20, /* Verity protected inode */
470 EXT4_INODE_EA_INODE = 21, /* Inode used for large EA */ 473 EXT4_INODE_EA_INODE = 21, /* Inode used for large EA */
471 EXT4_INODE_EOFBLOCKS = 22, /* Blocks allocated beyond EOF */ 474 EXT4_INODE_EOFBLOCKS = 22, /* Blocks allocated beyond EOF */
472 EXT4_INODE_INLINE_DATA = 28, /* Data in inode. */ 475 EXT4_INODE_INLINE_DATA = 28, /* Data in inode. */
@@ -512,6 +515,7 @@ static inline void ext4_check_flag_values(void)
512 CHECK_FLAG_VALUE(TOPDIR); 515 CHECK_FLAG_VALUE(TOPDIR);
513 CHECK_FLAG_VALUE(HUGE_FILE); 516 CHECK_FLAG_VALUE(HUGE_FILE);
514 CHECK_FLAG_VALUE(EXTENTS); 517 CHECK_FLAG_VALUE(EXTENTS);
518 CHECK_FLAG_VALUE(VERITY);
515 CHECK_FLAG_VALUE(EA_INODE); 519 CHECK_FLAG_VALUE(EA_INODE);
516 CHECK_FLAG_VALUE(EOFBLOCKS); 520 CHECK_FLAG_VALUE(EOFBLOCKS);
517 CHECK_FLAG_VALUE(INLINE_DATA); 521 CHECK_FLAG_VALUE(INLINE_DATA);
@@ -1560,6 +1564,7 @@ enum {
1560 EXT4_STATE_MAY_INLINE_DATA, /* may have in-inode data */ 1564 EXT4_STATE_MAY_INLINE_DATA, /* may have in-inode data */
1561 EXT4_STATE_EXT_PRECACHED, /* extents have been precached */ 1565 EXT4_STATE_EXT_PRECACHED, /* extents have been precached */
1562 EXT4_STATE_LUSTRE_EA_INODE, /* Lustre-style ea_inode */ 1566 EXT4_STATE_LUSTRE_EA_INODE, /* Lustre-style ea_inode */
1567 EXT4_STATE_VERITY_IN_PROGRESS, /* building fs-verity Merkle tree */
1563}; 1568};
1564 1569
1565#define EXT4_INODE_BIT_FNS(name, field, offset) \ 1570#define EXT4_INODE_BIT_FNS(name, field, offset) \
@@ -1610,6 +1615,12 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei)
1610#define EXT4_SB(sb) (sb) 1615#define EXT4_SB(sb) (sb)
1611#endif 1616#endif
1612 1617
1618static inline bool ext4_verity_in_progress(struct inode *inode)
1619{
1620 return IS_ENABLED(CONFIG_FS_VERITY) &&
1621 ext4_test_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
1622}
1623
1613#define NEXT_ORPHAN(inode) EXT4_I(inode)->i_dtime 1624#define NEXT_ORPHAN(inode) EXT4_I(inode)->i_dtime
1614 1625
1615/* 1626/*
@@ -1662,6 +1673,7 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei)
1662#define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400 1673#define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400
1663#define EXT4_FEATURE_RO_COMPAT_READONLY 0x1000 1674#define EXT4_FEATURE_RO_COMPAT_READONLY 0x1000
1664#define EXT4_FEATURE_RO_COMPAT_PROJECT 0x2000 1675#define EXT4_FEATURE_RO_COMPAT_PROJECT 0x2000
1676#define EXT4_FEATURE_RO_COMPAT_VERITY 0x8000
1665 1677
1666#define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x0001 1678#define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x0001
1667#define EXT4_FEATURE_INCOMPAT_FILETYPE 0x0002 1679#define EXT4_FEATURE_INCOMPAT_FILETYPE 0x0002
@@ -1756,6 +1768,7 @@ EXT4_FEATURE_RO_COMPAT_FUNCS(bigalloc, BIGALLOC)
1756EXT4_FEATURE_RO_COMPAT_FUNCS(metadata_csum, METADATA_CSUM) 1768EXT4_FEATURE_RO_COMPAT_FUNCS(metadata_csum, METADATA_CSUM)
1757EXT4_FEATURE_RO_COMPAT_FUNCS(readonly, READONLY) 1769EXT4_FEATURE_RO_COMPAT_FUNCS(readonly, READONLY)
1758EXT4_FEATURE_RO_COMPAT_FUNCS(project, PROJECT) 1770EXT4_FEATURE_RO_COMPAT_FUNCS(project, PROJECT)
1771EXT4_FEATURE_RO_COMPAT_FUNCS(verity, VERITY)
1759 1772
1760EXT4_FEATURE_INCOMPAT_FUNCS(compression, COMPRESSION) 1773EXT4_FEATURE_INCOMPAT_FUNCS(compression, COMPRESSION)
1761EXT4_FEATURE_INCOMPAT_FUNCS(filetype, FILETYPE) 1774EXT4_FEATURE_INCOMPAT_FUNCS(filetype, FILETYPE)
@@ -1813,7 +1826,8 @@ EXT4_FEATURE_INCOMPAT_FUNCS(casefold, CASEFOLD)
1813 EXT4_FEATURE_RO_COMPAT_BIGALLOC |\ 1826 EXT4_FEATURE_RO_COMPAT_BIGALLOC |\
1814 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM|\ 1827 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM|\
1815 EXT4_FEATURE_RO_COMPAT_QUOTA |\ 1828 EXT4_FEATURE_RO_COMPAT_QUOTA |\
1816 EXT4_FEATURE_RO_COMPAT_PROJECT) 1829 EXT4_FEATURE_RO_COMPAT_PROJECT |\
1830 EXT4_FEATURE_RO_COMPAT_VERITY)
1817 1831
1818#define EXTN_FEATURE_FUNCS(ver) \ 1832#define EXTN_FEATURE_FUNCS(ver) \
1819static inline bool ext4_has_unknown_ext##ver##_compat_features(struct super_block *sb) \ 1833static inline bool ext4_has_unknown_ext##ver##_compat_features(struct super_block *sb) \
@@ -3283,6 +3297,9 @@ extern int ext4_bio_write_page(struct ext4_io_submit *io,
3283/* mmp.c */ 3297/* mmp.c */
3284extern int ext4_multi_mount_protect(struct super_block *, ext4_fsblk_t); 3298extern int ext4_multi_mount_protect(struct super_block *, ext4_fsblk_t);
3285 3299
3300/* verity.c */
3301extern const struct fsverity_operations ext4_verityops;
3302
3286/* 3303/*
3287 * Add new method to test whether block and inode bitmaps are properly 3304 * Add new method to test whether block and inode bitmaps are properly
3288 * initialized. With uninit_bg reading the block from disk is not enough 3305 * initialized. With uninit_bg reading the block from disk is not enough
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 70b0438dbc94..b8a20bb9a145 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -457,6 +457,10 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
457 if (ret) 457 if (ret)
458 return ret; 458 return ret;
459 459
460 ret = fsverity_file_open(inode, filp);
461 if (ret)
462 return ret;
463
460 /* 464 /*
461 * Set up the jbd2_inode if we are opening the inode for 465 * Set up the jbd2_inode if we are opening the inode for
462 * writing and the journal is present 466 * writing and the journal is present
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 420fe3deed39..6de3d4ba28f3 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1340,6 +1340,9 @@ retry_journal:
1340 } 1340 }
1341 1341
1342 if (ret) { 1342 if (ret) {
1343 bool extended = (pos + len > inode->i_size) &&
1344 !ext4_verity_in_progress(inode);
1345
1343 unlock_page(page); 1346 unlock_page(page);
1344 /* 1347 /*
1345 * __block_write_begin may have instantiated a few blocks 1348 * __block_write_begin may have instantiated a few blocks
@@ -1349,11 +1352,11 @@ retry_journal:
1349 * Add inode to orphan list in case we crash before 1352 * Add inode to orphan list in case we crash before
1350 * truncate finishes 1353 * truncate finishes
1351 */ 1354 */
1352 if (pos + len > inode->i_size && ext4_can_truncate(inode)) 1355 if (extended && ext4_can_truncate(inode))
1353 ext4_orphan_add(handle, inode); 1356 ext4_orphan_add(handle, inode);
1354 1357
1355 ext4_journal_stop(handle); 1358 ext4_journal_stop(handle);
1356 if (pos + len > inode->i_size) { 1359 if (extended) {
1357 ext4_truncate_failed_write(inode); 1360 ext4_truncate_failed_write(inode);
1358 /* 1361 /*
1359 * If truncate failed early the inode might 1362 * If truncate failed early the inode might
@@ -1406,6 +1409,7 @@ static int ext4_write_end(struct file *file,
1406 int ret = 0, ret2; 1409 int ret = 0, ret2;
1407 int i_size_changed = 0; 1410 int i_size_changed = 0;
1408 int inline_data = ext4_has_inline_data(inode); 1411 int inline_data = ext4_has_inline_data(inode);
1412 bool verity = ext4_verity_in_progress(inode);
1409 1413
1410 trace_ext4_write_end(inode, pos, len, copied); 1414 trace_ext4_write_end(inode, pos, len, copied);
1411 if (inline_data) { 1415 if (inline_data) {
@@ -1423,12 +1427,16 @@ static int ext4_write_end(struct file *file,
1423 /* 1427 /*
1424 * it's important to update i_size while still holding page lock: 1428 * it's important to update i_size while still holding page lock:
1425 * page writeout could otherwise come in and zero beyond i_size. 1429 * page writeout could otherwise come in and zero beyond i_size.
1430 *
1431 * If FS_IOC_ENABLE_VERITY is running on this inode, then Merkle tree
1432 * blocks are being written past EOF, so skip the i_size update.
1426 */ 1433 */
1427 i_size_changed = ext4_update_inode_size(inode, pos + copied); 1434 if (!verity)
1435 i_size_changed = ext4_update_inode_size(inode, pos + copied);
1428 unlock_page(page); 1436 unlock_page(page);
1429 put_page(page); 1437 put_page(page);
1430 1438
1431 if (old_size < pos) 1439 if (old_size < pos && !verity)
1432 pagecache_isize_extended(inode, old_size, pos); 1440 pagecache_isize_extended(inode, old_size, pos);
1433 /* 1441 /*
1434 * Don't mark the inode dirty under page lock. First, it unnecessarily 1442 * Don't mark the inode dirty under page lock. First, it unnecessarily
@@ -1439,7 +1447,7 @@ static int ext4_write_end(struct file *file,
1439 if (i_size_changed || inline_data) 1447 if (i_size_changed || inline_data)
1440 ext4_mark_inode_dirty(handle, inode); 1448 ext4_mark_inode_dirty(handle, inode);
1441 1449
1442 if (pos + len > inode->i_size && ext4_can_truncate(inode)) 1450 if (pos + len > inode->i_size && !verity && ext4_can_truncate(inode))
1443 /* if we have allocated more blocks and copied 1451 /* if we have allocated more blocks and copied
1444 * less. We will have blocks allocated outside 1452 * less. We will have blocks allocated outside
1445 * inode->i_size. So truncate them 1453 * inode->i_size. So truncate them
@@ -1450,7 +1458,7 @@ errout:
1450 if (!ret) 1458 if (!ret)
1451 ret = ret2; 1459 ret = ret2;
1452 1460
1453 if (pos + len > inode->i_size) { 1461 if (pos + len > inode->i_size && !verity) {
1454 ext4_truncate_failed_write(inode); 1462 ext4_truncate_failed_write(inode);
1455 /* 1463 /*
1456 * If truncate failed early the inode might still be 1464 * If truncate failed early the inode might still be
@@ -1511,6 +1519,7 @@ static int ext4_journalled_write_end(struct file *file,
1511 unsigned from, to; 1519 unsigned from, to;
1512 int size_changed = 0; 1520 int size_changed = 0;
1513 int inline_data = ext4_has_inline_data(inode); 1521 int inline_data = ext4_has_inline_data(inode);
1522 bool verity = ext4_verity_in_progress(inode);
1514 1523
1515 trace_ext4_journalled_write_end(inode, pos, len, copied); 1524 trace_ext4_journalled_write_end(inode, pos, len, copied);
1516 from = pos & (PAGE_SIZE - 1); 1525 from = pos & (PAGE_SIZE - 1);
@@ -1540,13 +1549,14 @@ static int ext4_journalled_write_end(struct file *file,
1540 if (!partial) 1549 if (!partial)
1541 SetPageUptodate(page); 1550 SetPageUptodate(page);
1542 } 1551 }
1543 size_changed = ext4_update_inode_size(inode, pos + copied); 1552 if (!verity)
1553 size_changed = ext4_update_inode_size(inode, pos + copied);
1544 ext4_set_inode_state(inode, EXT4_STATE_JDATA); 1554 ext4_set_inode_state(inode, EXT4_STATE_JDATA);
1545 EXT4_I(inode)->i_datasync_tid = handle->h_transaction->t_tid; 1555 EXT4_I(inode)->i_datasync_tid = handle->h_transaction->t_tid;
1546 unlock_page(page); 1556 unlock_page(page);
1547 put_page(page); 1557 put_page(page);
1548 1558
1549 if (old_size < pos) 1559 if (old_size < pos && !verity)
1550 pagecache_isize_extended(inode, old_size, pos); 1560 pagecache_isize_extended(inode, old_size, pos);
1551 1561
1552 if (size_changed || inline_data) { 1562 if (size_changed || inline_data) {
@@ -1555,7 +1565,7 @@ static int ext4_journalled_write_end(struct file *file,
1555 ret = ret2; 1565 ret = ret2;
1556 } 1566 }
1557 1567
1558 if (pos + len > inode->i_size && ext4_can_truncate(inode)) 1568 if (pos + len > inode->i_size && !verity && ext4_can_truncate(inode))
1559 /* if we have allocated more blocks and copied 1569 /* if we have allocated more blocks and copied
1560 * less. We will have blocks allocated outside 1570 * less. We will have blocks allocated outside
1561 * inode->i_size. So truncate them 1571 * inode->i_size. So truncate them
@@ -1566,7 +1576,7 @@ errout:
1566 ret2 = ext4_journal_stop(handle); 1576 ret2 = ext4_journal_stop(handle);
1567 if (!ret) 1577 if (!ret)
1568 ret = ret2; 1578 ret = ret2;
1569 if (pos + len > inode->i_size) { 1579 if (pos + len > inode->i_size && !verity) {
1570 ext4_truncate_failed_write(inode); 1580 ext4_truncate_failed_write(inode);
1571 /* 1581 /*
1572 * If truncate failed early the inode might still be 1582 * If truncate failed early the inode might still be
@@ -2162,7 +2172,8 @@ static int ext4_writepage(struct page *page,
2162 2172
2163 trace_ext4_writepage(page); 2173 trace_ext4_writepage(page);
2164 size = i_size_read(inode); 2174 size = i_size_read(inode);
2165 if (page->index == size >> PAGE_SHIFT) 2175 if (page->index == size >> PAGE_SHIFT &&
2176 !ext4_verity_in_progress(inode))
2166 len = size & ~PAGE_MASK; 2177 len = size & ~PAGE_MASK;
2167 else 2178 else
2168 len = PAGE_SIZE; 2179 len = PAGE_SIZE;
@@ -2246,7 +2257,8 @@ static int mpage_submit_page(struct mpage_da_data *mpd, struct page *page)
2246 * after page tables are updated. 2257 * after page tables are updated.
2247 */ 2258 */
2248 size = i_size_read(mpd->inode); 2259 size = i_size_read(mpd->inode);
2249 if (page->index == size >> PAGE_SHIFT) 2260 if (page->index == size >> PAGE_SHIFT &&
2261 !ext4_verity_in_progress(mpd->inode))
2250 len = size & ~PAGE_MASK; 2262 len = size & ~PAGE_MASK;
2251 else 2263 else
2252 len = PAGE_SIZE; 2264 len = PAGE_SIZE;
@@ -2345,6 +2357,9 @@ static int mpage_process_page_bufs(struct mpage_da_data *mpd,
2345 ext4_lblk_t blocks = (i_size_read(inode) + i_blocksize(inode) - 1) 2357 ext4_lblk_t blocks = (i_size_read(inode) + i_blocksize(inode) - 1)
2346 >> inode->i_blkbits; 2358 >> inode->i_blkbits;
2347 2359
2360 if (ext4_verity_in_progress(inode))
2361 blocks = EXT_MAX_BLOCKS;
2362
2348 do { 2363 do {
2349 BUG_ON(buffer_locked(bh)); 2364 BUG_ON(buffer_locked(bh));
2350 2365
@@ -3061,8 +3076,8 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
3061 3076
3062 index = pos >> PAGE_SHIFT; 3077 index = pos >> PAGE_SHIFT;
3063 3078
3064 if (ext4_nonda_switch(inode->i_sb) || 3079 if (ext4_nonda_switch(inode->i_sb) || S_ISLNK(inode->i_mode) ||
3065 S_ISLNK(inode->i_mode)) { 3080 ext4_verity_in_progress(inode)) {
3066 *fsdata = (void *)FALL_BACK_TO_NONDELALLOC; 3081 *fsdata = (void *)FALL_BACK_TO_NONDELALLOC;
3067 return ext4_write_begin(file, mapping, pos, 3082 return ext4_write_begin(file, mapping, pos,
3068 len, flags, pagep, fsdata); 3083 len, flags, pagep, fsdata);
@@ -4739,6 +4754,8 @@ static bool ext4_should_use_dax(struct inode *inode)
4739 return false; 4754 return false;
4740 if (ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT)) 4755 if (ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT))
4741 return false; 4756 return false;
4757 if (ext4_test_inode_flag(inode, EXT4_INODE_VERITY))
4758 return false;
4742 return true; 4759 return true;
4743} 4760}
4744 4761
@@ -4763,9 +4780,11 @@ void ext4_set_inode_flags(struct inode *inode)
4763 new_fl |= S_ENCRYPTED; 4780 new_fl |= S_ENCRYPTED;
4764 if (flags & EXT4_CASEFOLD_FL) 4781 if (flags & EXT4_CASEFOLD_FL)
4765 new_fl |= S_CASEFOLD; 4782 new_fl |= S_CASEFOLD;
4783 if (flags & EXT4_VERITY_FL)
4784 new_fl |= S_VERITY;
4766 inode_set_flags(inode, new_fl, 4785 inode_set_flags(inode, new_fl,
4767 S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX| 4786 S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX|
4768 S_ENCRYPTED|S_CASEFOLD); 4787 S_ENCRYPTED|S_CASEFOLD|S_VERITY);
4769} 4788}
4770 4789
4771static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode, 4790static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
@@ -5555,6 +5574,10 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
5555 if (error) 5574 if (error)
5556 return error; 5575 return error;
5557 5576
5577 error = fsverity_prepare_setattr(dentry, attr);
5578 if (error)
5579 return error;
5580
5558 if (is_quota_modification(inode, attr)) { 5581 if (is_quota_modification(inode, attr)) {
5559 error = dquot_initialize(inode); 5582 error = dquot_initialize(inode);
5560 if (error) 5583 if (error)
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 442f7ef873fc..ce811df71690 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -1171,6 +1171,17 @@ out:
1171 } 1171 }
1172 case EXT4_IOC_SHUTDOWN: 1172 case EXT4_IOC_SHUTDOWN:
1173 return ext4_shutdown(sb, arg); 1173 return ext4_shutdown(sb, arg);
1174
1175 case FS_IOC_ENABLE_VERITY:
1176 if (!ext4_has_feature_verity(sb))
1177 return -EOPNOTSUPP;
1178 return fsverity_ioctl_enable(filp, (const void __user *)arg);
1179
1180 case FS_IOC_MEASURE_VERITY:
1181 if (!ext4_has_feature_verity(sb))
1182 return -EOPNOTSUPP;
1183 return fsverity_ioctl_measure(filp, (void __user *)arg);
1184
1174 default: 1185 default:
1175 return -ENOTTY; 1186 return -ENOTTY;
1176 } 1187 }
@@ -1233,6 +1244,8 @@ long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1233 case EXT4_IOC_GET_ENCRYPTION_POLICY: 1244 case EXT4_IOC_GET_ENCRYPTION_POLICY:
1234 case EXT4_IOC_SHUTDOWN: 1245 case EXT4_IOC_SHUTDOWN:
1235 case FS_IOC_GETFSMAP: 1246 case FS_IOC_GETFSMAP:
1247 case FS_IOC_ENABLE_VERITY:
1248 case FS_IOC_MEASURE_VERITY:
1236 break; 1249 break;
1237 default: 1250 default:
1238 return -ENOIOCTLCMD; 1251 return -ENOIOCTLCMD;
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 4079605d437a..05a9874687c3 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1179,6 +1179,7 @@ void ext4_clear_inode(struct inode *inode)
1179 EXT4_I(inode)->jinode = NULL; 1179 EXT4_I(inode)->jinode = NULL;
1180 } 1180 }
1181 fscrypt_put_encryption_info(inode); 1181 fscrypt_put_encryption_info(inode);
1182 fsverity_cleanup_inode(inode);
1182} 1183}
1183 1184
1184static struct inode *ext4_nfs_get_inode(struct super_block *sb, 1185static struct inode *ext4_nfs_get_inode(struct super_block *sb,
@@ -4272,6 +4273,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
4272#ifdef CONFIG_FS_ENCRYPTION 4273#ifdef CONFIG_FS_ENCRYPTION
4273 sb->s_cop = &ext4_cryptops; 4274 sb->s_cop = &ext4_cryptops;
4274#endif 4275#endif
4276#ifdef CONFIG_FS_VERITY
4277 sb->s_vop = &ext4_verityops;
4278#endif
4275#ifdef CONFIG_QUOTA 4279#ifdef CONFIG_QUOTA
4276 sb->dq_op = &ext4_quota_operations; 4280 sb->dq_op = &ext4_quota_operations;
4277 if (ext4_has_feature_quota(sb)) 4281 if (ext4_has_feature_quota(sb))
@@ -4419,6 +4423,11 @@ no_journal:
4419 goto failed_mount_wq; 4423 goto failed_mount_wq;
4420 } 4424 }
4421 4425
4426 if (ext4_has_feature_verity(sb) && blocksize != PAGE_SIZE) {
4427 ext4_msg(sb, KERN_ERR, "Unsupported blocksize for fs-verity");
4428 goto failed_mount_wq;
4429 }
4430
4422 if (DUMMY_ENCRYPTION_ENABLED(sbi) && !sb_rdonly(sb) && 4431 if (DUMMY_ENCRYPTION_ENABLED(sbi) && !sb_rdonly(sb) &&
4423 !ext4_has_feature_encrypt(sb)) { 4432 !ext4_has_feature_encrypt(sb)) {
4424 ext4_set_feature_encrypt(sb); 4433 ext4_set_feature_encrypt(sb);
diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
index b3cd7655a6ff..eb1efad0e20a 100644
--- a/fs/ext4/sysfs.c
+++ b/fs/ext4/sysfs.c
@@ -242,6 +242,9 @@ EXT4_ATTR_FEATURE(encryption);
242#ifdef CONFIG_UNICODE 242#ifdef CONFIG_UNICODE
243EXT4_ATTR_FEATURE(casefold); 243EXT4_ATTR_FEATURE(casefold);
244#endif 244#endif
245#ifdef CONFIG_FS_VERITY
246EXT4_ATTR_FEATURE(verity);
247#endif
245EXT4_ATTR_FEATURE(metadata_csum_seed); 248EXT4_ATTR_FEATURE(metadata_csum_seed);
246 249
247static struct attribute *ext4_feat_attrs[] = { 250static struct attribute *ext4_feat_attrs[] = {
@@ -254,6 +257,9 @@ static struct attribute *ext4_feat_attrs[] = {
254#ifdef CONFIG_UNICODE 257#ifdef CONFIG_UNICODE
255 ATTR_LIST(casefold), 258 ATTR_LIST(casefold),
256#endif 259#endif
260#ifdef CONFIG_FS_VERITY
261 ATTR_LIST(verity),
262#endif
257 ATTR_LIST(metadata_csum_seed), 263 ATTR_LIST(metadata_csum_seed),
258 NULL, 264 NULL,
259}; 265};
diff --git a/fs/ext4/verity.c b/fs/ext4/verity.c
new file mode 100644
index 000000000000..d0d8a9795dd6
--- /dev/null
+++ b/fs/ext4/verity.c
@@ -0,0 +1,367 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * fs/ext4/verity.c: fs-verity support for ext4
4 *
5 * Copyright 2019 Google LLC
6 */
7
8/*
9 * Implementation of fsverity_operations for ext4.
10 *
11 * ext4 stores the verity metadata (Merkle tree and fsverity_descriptor) past
12 * the end of the file, starting at the first 64K boundary beyond i_size. This
13 * approach works because (a) verity files are readonly, and (b) pages fully
14 * beyond i_size aren't visible to userspace but can be read/written internally
15 * by ext4 with only some relatively small changes to ext4. This approach
16 * avoids having to depend on the EA_INODE feature and on rearchitecturing
17 * ext4's xattr support to support paging multi-gigabyte xattrs into memory, and
18 * to support encrypting xattrs. Note that the verity metadata *must* be
19 * encrypted when the file is, since it contains hashes of the plaintext data.
20 *
21 * Using a 64K boundary rather than a 4K one keeps things ready for
22 * architectures with 64K pages, and it doesn't necessarily waste space on-disk
23 * since there can be a hole between i_size and the start of the Merkle tree.
24 */
25
26#include <linux/quotaops.h>
27
28#include "ext4.h"
29#include "ext4_extents.h"
30#include "ext4_jbd2.h"
31
32static inline loff_t ext4_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
109static int ext4_begin_enable_verity(struct file *filp)
110{
111 struct inode *inode = file_inode(filp);
112 const int credits = 2; /* superblock and inode for ext4_orphan_add() */
113 handle_t *handle;
114 int err;
115
116 if (ext4_verity_in_progress(inode))
117 return -EBUSY;
118
119 /*
120 * Since the file was opened readonly, we have to initialize the jbd
121 * inode and quotas here and not rely on ->open() doing it. This must
122 * be done before evicting the inline data.
123 */
124
125 err = ext4_inode_attach_jinode(inode);
126 if (err)
127 return err;
128
129 err = dquot_initialize(inode);
130 if (err)
131 return err;
132
133 err = ext4_convert_inline_data(inode);
134 if (err)
135 return err;
136
137 if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
138 ext4_warning_inode(inode,
139 "verity is only allowed on extent-based files");
140 return -EOPNOTSUPP;
141 }
142
143 /*
144 * ext4 uses the last allocated block to find the verity descriptor, so
145 * we must remove any other blocks past EOF which might confuse things.
146 */
147 err = ext4_truncate(inode);
148 if (err)
149 return err;
150
151 handle = ext4_journal_start(inode, EXT4_HT_INODE, credits);
152 if (IS_ERR(handle))
153 return PTR_ERR(handle);
154
155 err = ext4_orphan_add(handle, inode);
156 if (err == 0)
157 ext4_set_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
158
159 ext4_journal_stop(handle);
160 return err;
161}
162
163/*
164 * ext4 stores the verity descriptor beginning on the next filesystem block
165 * boundary after the Merkle tree. Then, the descriptor size is stored in the
166 * last 4 bytes of the last allocated filesystem block --- which is either the
167 * block in which the descriptor ends, or the next block after that if there
168 * weren't at least 4 bytes remaining.
169 *
170 * We can't simply store the descriptor in an xattr because it *must* be
171 * encrypted when ext4 encryption is used, but ext4 encryption doesn't encrypt
172 * xattrs. Also, if the descriptor includes a large signature blob it may be
173 * too large to store in an xattr without the EA_INODE feature.
174 */
175static int ext4_write_verity_descriptor(struct inode *inode, const void *desc,
176 size_t desc_size, u64 merkle_tree_size)
177{
178 const u64 desc_pos = round_up(ext4_verity_metadata_pos(inode) +
179 merkle_tree_size, i_blocksize(inode));
180 const u64 desc_end = desc_pos + desc_size;
181 const __le32 desc_size_disk = cpu_to_le32(desc_size);
182 const u64 desc_size_pos = round_up(desc_end + sizeof(desc_size_disk),
183 i_blocksize(inode)) -
184 sizeof(desc_size_disk);
185 int err;
186
187 err = pagecache_write(inode, desc, desc_size, desc_pos);
188 if (err)
189 return err;
190
191 return pagecache_write(inode, &desc_size_disk, sizeof(desc_size_disk),
192 desc_size_pos);
193}
194
195static int ext4_end_enable_verity(struct file *filp, const void *desc,
196 size_t desc_size, u64 merkle_tree_size)
197{
198 struct inode *inode = file_inode(filp);
199 const int credits = 2; /* superblock and inode for ext4_orphan_del() */
200 handle_t *handle;
201 int err = 0;
202 int err2;
203
204 if (desc != NULL) {
205 /* Succeeded; write the verity descriptor. */
206 err = ext4_write_verity_descriptor(inode, desc, desc_size,
207 merkle_tree_size);
208
209 /* Write all pages before clearing VERITY_IN_PROGRESS. */
210 if (!err)
211 err = filemap_write_and_wait(inode->i_mapping);
212 }
213
214 /* If we failed, truncate anything we wrote past i_size. */
215 if (desc == NULL || err)
216 ext4_truncate(inode);
217
218 /*
219 * We must always clean up by clearing EXT4_STATE_VERITY_IN_PROGRESS and
220 * deleting the inode from the orphan list, even if something failed.
221 * If everything succeeded, we'll also set the verity bit in the same
222 * transaction.
223 */
224
225 ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
226
227 handle = ext4_journal_start(inode, EXT4_HT_INODE, credits);
228 if (IS_ERR(handle)) {
229 ext4_orphan_del(NULL, inode);
230 return PTR_ERR(handle);
231 }
232
233 err2 = ext4_orphan_del(handle, inode);
234 if (err2)
235 goto out_stop;
236
237 if (desc != NULL && !err) {
238 struct ext4_iloc iloc;
239
240 err = ext4_reserve_inode_write(handle, inode, &iloc);
241 if (err)
242 goto out_stop;
243 ext4_set_inode_flag(inode, EXT4_INODE_VERITY);
244 ext4_set_inode_flags(inode);
245 err = ext4_mark_iloc_dirty(handle, inode, &iloc);
246 }
247out_stop:
248 ext4_journal_stop(handle);
249 return err ?: err2;
250}
251
252static int ext4_get_verity_descriptor_location(struct inode *inode,
253 size_t *desc_size_ret,
254 u64 *desc_pos_ret)
255{
256 struct ext4_ext_path *path;
257 struct ext4_extent *last_extent;
258 u32 end_lblk;
259 u64 desc_size_pos;
260 __le32 desc_size_disk;
261 u32 desc_size;
262 u64 desc_pos;
263 int err;
264
265 /*
266 * Descriptor size is in last 4 bytes of last allocated block.
267 * See ext4_write_verity_descriptor().
268 */
269
270 if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
271 EXT4_ERROR_INODE(inode, "verity file doesn't use extents");
272 return -EFSCORRUPTED;
273 }
274
275 path = ext4_find_extent(inode, EXT_MAX_BLOCKS - 1, NULL, 0);
276 if (IS_ERR(path))
277 return PTR_ERR(path);
278
279 last_extent = path[path->p_depth].p_ext;
280 if (!last_extent) {
281 EXT4_ERROR_INODE(inode, "verity file has no extents");
282 ext4_ext_drop_refs(path);
283 kfree(path);
284 return -EFSCORRUPTED;
285 }
286
287 end_lblk = le32_to_cpu(last_extent->ee_block) +
288 ext4_ext_get_actual_len(last_extent);
289 desc_size_pos = (u64)end_lblk << inode->i_blkbits;
290 ext4_ext_drop_refs(path);
291 kfree(path);
292
293 if (desc_size_pos < sizeof(desc_size_disk))
294 goto bad;
295 desc_size_pos -= sizeof(desc_size_disk);
296
297 err = pagecache_read(inode, &desc_size_disk, sizeof(desc_size_disk),
298 desc_size_pos);
299 if (err)
300 return err;
301 desc_size = le32_to_cpu(desc_size_disk);
302
303 /*
304 * The descriptor is stored just before the desc_size_disk, but starting
305 * on a filesystem block boundary.
306 */
307
308 if (desc_size > INT_MAX || desc_size > desc_size_pos)
309 goto bad;
310
311 desc_pos = round_down(desc_size_pos - desc_size, i_blocksize(inode));
312 if (desc_pos < ext4_verity_metadata_pos(inode))
313 goto bad;
314
315 *desc_size_ret = desc_size;
316 *desc_pos_ret = desc_pos;
317 return 0;
318
319bad:
320 EXT4_ERROR_INODE(inode, "verity file corrupted; can't find descriptor");
321 return -EFSCORRUPTED;
322}
323
324static int ext4_get_verity_descriptor(struct inode *inode, void *buf,
325 size_t buf_size)
326{
327 size_t desc_size = 0;
328 u64 desc_pos = 0;
329 int err;
330
331 err = ext4_get_verity_descriptor_location(inode, &desc_size, &desc_pos);
332 if (err)
333 return err;
334
335 if (buf_size) {
336 if (desc_size > buf_size)
337 return -ERANGE;
338 err = pagecache_read(inode, buf, desc_size, desc_pos);
339 if (err)
340 return err;
341 }
342 return desc_size;
343}
344
345static struct page *ext4_read_merkle_tree_page(struct inode *inode,
346 pgoff_t index)
347{
348 index += ext4_verity_metadata_pos(inode) >> PAGE_SHIFT;
349
350 return read_mapping_page(inode->i_mapping, index, NULL);
351}
352
353static int ext4_write_merkle_tree_block(struct inode *inode, const void *buf,
354 u64 index, int log_blocksize)
355{
356 loff_t pos = ext4_verity_metadata_pos(inode) + (index << log_blocksize);
357
358 return pagecache_write(inode, buf, 1 << log_blocksize, pos);
359}
360
361const struct fsverity_operations ext4_verityops = {
362 .begin_enable_verity = ext4_begin_enable_verity,
363 .end_enable_verity = ext4_end_enable_verity,
364 .get_verity_descriptor = ext4_get_verity_descriptor,
365 .read_merkle_tree_page = ext4_read_merkle_tree_page,
366 .write_merkle_tree_block = ext4_write_merkle_tree_block,
367};