On Wed, Mar 13, 2024 at 10:58:03AM -0700, Darrick J. Wong wrote: > From: Andrey Albershteyn <aalbersh@xxxxxxxxxx> > > Add integration with fs-verity. The XFS store fs-verity metadata in > the extended file attributes. The metadata consist of verity > descriptor and Merkle tree blocks. > > The descriptor is stored under "vdesc" extended attribute. The > Merkle tree blocks are stored under binary indexes which are offsets > into the Merkle tree. > > When fs-verity is enabled on an inode, the XFS_IVERITY_CONSTRUCTION > flag is set meaning that the Merkle tree is being build. The > initialization ends with storing of verity descriptor and setting > inode on-disk flag (XFS_DIFLAG2_VERITY). > > The verification on read is done in read path of iomap. > > Signed-off-by: Andrey Albershteyn <aalbersh@xxxxxxxxxx> > Reviewed-by: Darrick J. Wong <djwong@xxxxxxxxxx> > [djwong: replace caching implementation with an xarray, other cleanups] > Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> I started writing more of userspace (xfs_db decoding of verity xattrs, repair/scrub support) so I think I want to make one more change to this. This change shortens the key structure name, puts a proper namespace on the merkleoff field to match everything else in the ondisk structs, and checks it via xfs_ondisk.h. --D diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 3280fbc3027ec..c2f1b38683646 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -1593,7 +1593,7 @@ xfs_attr_namecheck( if (flags & XFS_ATTR_VERITY) { /* Merkle tree pages are stored under u64 indexes */ - if (length == sizeof(struct xfs_fsverity_merkle_key)) + if (length == sizeof(struct xfs_verity_merkle_key)) return true; /* Verity descriptor blocks are held in a named attribute. */ diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h index 6e3b08d4ad74a..e55e437c47ae3 100644 --- a/fs/xfs/libxfs/xfs_da_format.h +++ b/fs/xfs/libxfs/xfs_da_format.h @@ -923,10 +923,10 @@ struct xfs_parent_name_rec { * fs-verity attribute name format * * Merkle tree blocks are stored under extended attributes of the inode. The - * name of the attributes are offsets into merkle tree. + * name of the attributes are byte offsets into merkle tree. */ -struct xfs_fsverity_merkle_key { - __be64 merkleoff; +struct xfs_verity_merkle_key { + __be64 bk_merkleoff; }; /* ondisk xattr name used for the fsverity descriptor */ diff --git a/fs/xfs/libxfs/xfs_ondisk.h b/fs/xfs/libxfs/xfs_ondisk.h index e4e0e5203ec16..118e993c7d2f3 100644 --- a/fs/xfs/libxfs/xfs_ondisk.h +++ b/fs/xfs/libxfs/xfs_ondisk.h @@ -206,8 +206,9 @@ xfs_check_ondisk_structs(void) XFS_CHECK_VALUE(XFS_DQ_BIGTIME_EXPIRY_MAX << XFS_DQ_BIGTIME_SHIFT, 16299260424LL); - /* fs-verity descriptor xattr name */ - XFS_CHECK_VALUE(sizeof(XFS_VERITY_DESCRIPTOR_NAME), 6); + /* fs-verity xattrs */ + XFS_CHECK_STRUCT_SIZE(struct xfs_verity_merkle_key, 8); + XFS_CHECK_VALUE(sizeof(XFS_VERITY_DESCRIPTOR_NAME), 6); } #endif /* __XFS_ONDISK_H */ diff --git a/fs/xfs/xfs_verity.c b/fs/xfs/xfs_verity.c index 82340c9130494..dca3b68445343 100644 --- a/fs/xfs/xfs_verity.c +++ b/fs/xfs/xfs_verity.c @@ -201,20 +201,20 @@ xfs_verity_cache_store( } static inline void -xfs_fsverity_merkle_key_to_disk( - struct xfs_fsverity_merkle_key *key, +xfs_verity_merkle_key_to_disk( + struct xfs_verity_merkle_key *key, u64 offset) { - key->merkleoff = cpu_to_be64(offset); + key->bk_merkleoff = cpu_to_be64(offset); } static inline u64 -xfs_fsverity_merkle_key_from_disk( +xfs_verity_merkle_key_from_disk( void *attr_name) { - struct xfs_fsverity_merkle_key *key = attr_name; + struct xfs_verity_merkle_key *key = attr_name; - return be64_to_cpu(key->merkleoff); + return be64_to_cpu(key->bk_merkleoff); } static int @@ -272,7 +272,7 @@ xfs_drop_merkle_tree( u64 merkle_tree_size, unsigned int tree_blocksize) { - struct xfs_fsverity_merkle_key name; + struct xfs_verity_merkle_key name; int error = 0; u64 offset = 0; struct xfs_da_args args = { @@ -281,7 +281,7 @@ xfs_drop_merkle_tree( .attr_filter = XFS_ATTR_VERITY, .op_flags = XFS_DA_OP_REMOVE, .name = (const uint8_t *)&name, - .namelen = sizeof(struct xfs_fsverity_merkle_key), + .namelen = sizeof(struct xfs_verity_merkle_key), /* NULL value make xfs_attr_set remove the attr */ .value = NULL, }; @@ -290,7 +290,7 @@ xfs_drop_merkle_tree( return 0; for (offset = 0; offset < merkle_tree_size; offset += tree_blocksize) { - xfs_fsverity_merkle_key_to_disk(&name, offset); + xfs_verity_merkle_key_to_disk(&name, offset); error = xfs_attr_set(&args); if (error) return error; @@ -372,12 +372,12 @@ xfs_verity_read_merkle( struct fsverity_blockbuf *block) { struct xfs_inode *ip = XFS_I(req->inode); - struct xfs_fsverity_merkle_key name; + struct xfs_verity_merkle_key name; struct xfs_da_args args = { .dp = ip, .attr_filter = XFS_ATTR_VERITY, .name = (const uint8_t *)&name, - .namelen = sizeof(struct xfs_fsverity_merkle_key), + .namelen = sizeof(struct xfs_verity_merkle_key), .valuelen = block->size, }; struct xfs_merkle_blob *mk, *new_mk; @@ -386,7 +386,7 @@ xfs_verity_read_merkle( ASSERT(block->offset >> req->log_blocksize <= ULONG_MAX); - xfs_fsverity_merkle_key_to_disk(&name, block->offset); + xfs_verity_merkle_key_to_disk(&name, block->offset); /* Is the block already cached? */ mk = xfs_verity_cache_load(ip, key); @@ -399,7 +399,7 @@ xfs_verity_read_merkle( args.value = new_mk->data; /* Read the block in from disk and try to store it in the cache. */ - xfs_fsverity_merkle_key_to_disk(&name, block->offset); + xfs_verity_merkle_key_to_disk(&name, block->offset); error = xfs_attr_get(&args); if (error) @@ -440,19 +440,18 @@ xfs_verity_write_merkle( unsigned int size) { struct xfs_inode *ip = XFS_I(inode); - struct xfs_fsverity_merkle_key name; + struct xfs_verity_merkle_key name; struct xfs_da_args args = { .dp = ip, .whichfork = XFS_ATTR_FORK, .attr_filter = XFS_ATTR_VERITY, - .namelen = sizeof(struct xfs_fsverity_merkle_key), + .name = (const uint8_t *)&name, + .namelen = sizeof(struct xfs_verity_merkle_key), .value = (void *)buf, .valuelen = size, }; - xfs_fsverity_merkle_key_to_disk(&name, pos); - args.name = (const uint8_t *)&name.merkleoff; - + xfs_verity_merkle_key_to_disk(&name, pos); return xfs_attr_set(&args); }