ext4: add basic fs-verity support
Add most of fs-verity support to ext4. fs-verity is a filesystem feature that enables transparent integrity protection and authentication of read-only files. It uses a dm-verity like mechanism at the file level: a Merkle tree is used to verify any block in the file in log(filesize) time. It is implemented mainly by helper functions in fs/verity/. See Documentation/filesystems/fsverity.rst for the full documentation. This commit adds all of ext4 fs-verity support except for the actual data verification, including: - Adding a filesystem feature flag and an inode flag for fs-verity. - Implementing the fsverity_operations to support enabling verity on an inode and reading/writing the verity metadata. - Updating ->write_begin(), ->write_end(), and ->writepages() to support writing verity metadata pages. - Calling the fs-verity hooks for ->open(), ->setattr(), and ->ioctl(). ext4 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 ext4 with only some relatively small changes to ext4. This approach avoids having to depend on the EA_INODE feature and on rearchitecturing ext4's xattr support to support paging multi-gigabyte xattrs into memory, and to support encrypting xattrs. Note that the verity metadata *must* be encrypted when the file is, since it contains hashes of the plaintext data. This patch incorporates work by Theodore Ts'o and Chandan Rajendra. Reviewed-by: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Eric Biggers <ebiggers@google.com>
This commit is contained in:
@@ -1179,6 +1179,7 @@ void ext4_clear_inode(struct inode *inode)
|
||||
EXT4_I(inode)->jinode = NULL;
|
||||
}
|
||||
fscrypt_put_encryption_info(inode);
|
||||
fsverity_cleanup_inode(inode);
|
||||
}
|
||||
|
||||
static 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)
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
sb->s_cop = &ext4_cryptops;
|
||||
#endif
|
||||
#ifdef CONFIG_FS_VERITY
|
||||
sb->s_vop = &ext4_verityops;
|
||||
#endif
|
||||
#ifdef CONFIG_QUOTA
|
||||
sb->dq_op = &ext4_quota_operations;
|
||||
if (ext4_has_feature_quota(sb))
|
||||
@@ -4419,6 +4423,11 @@ no_journal:
|
||||
goto failed_mount_wq;
|
||||
}
|
||||
|
||||
if (ext4_has_feature_verity(sb) && blocksize != PAGE_SIZE) {
|
||||
ext4_msg(sb, KERN_ERR, "Unsupported blocksize for fs-verity");
|
||||
goto failed_mount_wq;
|
||||
}
|
||||
|
||||
if (DUMMY_ENCRYPTION_ENABLED(sbi) && !sb_rdonly(sb) &&
|
||||
!ext4_has_feature_encrypt(sb)) {
|
||||
ext4_set_feature_encrypt(sb);
|
||||
|
Reference in New Issue
Block a user