From: "Darrick J. Wong" <djwong@kernel.org>
To: Andrey Albershteyn <aalbersh@redhat.com>
Cc: fsverity@lists.linux.dev, linux-xfs@vger.kernel.org,
linux-fsdevel@vger.kernel.org, chandan.babu@oracle.com,
ebiggers@kernel.org
Subject: Re: [PATCH v5 21/24] xfs: add fs-verity support
Date: Thu, 7 Mar 2024 15:10:38 -0800 [thread overview]
Message-ID: <20240307231038.GC1927156@frogsfrogsfrogs> (raw)
In-Reply-To: <20240304191046.157464-23-aalbersh@redhat.com>
On Mon, Mar 04, 2024 at 08:10:44PM +0100, Andrey Albershteyn wrote:
> 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@redhat.com>
> ---
> fs/xfs/Makefile | 1 +
> fs/xfs/libxfs/xfs_attr.c | 13 ++
> fs/xfs/libxfs/xfs_attr_leaf.c | 17 +-
> fs/xfs/libxfs/xfs_attr_remote.c | 8 +-
> fs/xfs/libxfs/xfs_da_format.h | 27 +++
> fs/xfs/libxfs/xfs_ondisk.h | 4 +
> fs/xfs/xfs_inode.h | 3 +-
> fs/xfs/xfs_super.c | 10 +
> fs/xfs/xfs_verity.c | 355 ++++++++++++++++++++++++++++++++
> fs/xfs/xfs_verity.h | 33 +++
> 10 files changed, 464 insertions(+), 7 deletions(-)
> create mode 100644 fs/xfs/xfs_verity.c
> create mode 100644 fs/xfs/xfs_verity.h
>
> diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
> index f8845e65cac7..8396a633b541 100644
> --- a/fs/xfs/Makefile
> +++ b/fs/xfs/Makefile
> @@ -130,6 +130,7 @@ xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
> xfs-$(CONFIG_SYSCTL) += xfs_sysctl.o
> xfs-$(CONFIG_COMPAT) += xfs_ioctl32.o
> xfs-$(CONFIG_EXPORTFS_BLOCK_OPS) += xfs_pnfs.o
> +xfs-$(CONFIG_FS_VERITY) += xfs_verity.o
>
> # notify failure
> ifeq ($(CONFIG_MEMORY_FAILURE),y)
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index ca515e8bd2ed..cde5352db9aa 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -27,6 +27,7 @@
> #include "xfs_attr_item.h"
> #include "xfs_xattr.h"
> #include "xfs_parent.h"
> +#include "xfs_verity.h"
>
> struct kmem_cache *xfs_attr_intent_cache;
>
> @@ -1527,6 +1528,18 @@ xfs_attr_namecheck(
> if (flags & XFS_ATTR_PARENT)
> return xfs_parent_namecheck(mp, name, length, flags);
>
> + if (flags & XFS_ATTR_VERITY) {
> + /* Merkle tree pages are stored under u64 indexes */
> + if (length == sizeof(struct xfs_fsverity_merkle_key))
> + return true;
> +
> + /* Verity descriptor blocks are held in a named attribute. */
> + if (length == XFS_VERITY_DESCRIPTOR_NAME_LEN)
> + return true;
> +
> + return false;
> + }
> +
> /*
> * MAXNAMELEN includes the trailing null, but (name/length) leave it
> * out, so use >= for the length check.
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
> index b51f439e4aed..f1f6aefc0420 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.c
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.c
> @@ -30,6 +30,7 @@
> #include "xfs_ag.h"
> #include "xfs_errortag.h"
> #include "xfs_health.h"
> +#include "xfs_verity.h"
>
>
> /*
> @@ -519,7 +520,12 @@ xfs_attr_copy_value(
> return -ERANGE;
> }
>
> - if (!args->value) {
> + /*
> + * We don't want to allocate memory for fs-verity Merkle tree blocks
> + * (fs-verity descriptor is fine though). They will be stored in
> + * underlying xfs_buf
> + */
> + if (!args->value && !xfs_verity_merkle_block(args)) {
> args->value = kvmalloc(valuelen, GFP_KERNEL | __GFP_NOLOCKDEP);
> if (!args->value)
> return -ENOMEM;
> @@ -538,7 +544,14 @@ xfs_attr_copy_value(
> */
> if (!value)
> return -EINVAL;
> - memcpy(args->value, value, valuelen);
> + /*
> + * We won't copy Merkle tree block to the args->value as we want it be
> + * in the xfs_buf. And we didn't allocate any memory in args->value.
> + */
> + if (xfs_verity_merkle_block(args))
> + args->value = value;
> + else
> + memcpy(args->value, value, valuelen);
> return 0;
> }
>
> diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
> index f1b7842da809..a631ddff8068 100644
> --- a/fs/xfs/libxfs/xfs_attr_remote.c
> +++ b/fs/xfs/libxfs/xfs_attr_remote.c
> @@ -23,6 +23,7 @@
> #include "xfs_trace.h"
> #include "xfs_error.h"
> #include "xfs_health.h"
> +#include "xfs_verity.h"
>
> #define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */
>
> @@ -404,11 +405,10 @@ xfs_attr_rmtval_get(
> ASSERT(args->rmtvaluelen == args->valuelen);
>
> /*
> - * We also check for _OP_BUFFER as we want to trigger on
> - * verity blocks only, not on verity_descriptor
> + * For fs-verity we want additional space in the xfs_buf. This space is
> + * used to copy xattr value without leaf headers (crc header).
> */
> - if (args->attr_filter & XFS_ATTR_VERITY &&
> - args->op_flags & XFS_DA_OP_BUFFER)
> + if (xfs_verity_merkle_block(args))
> flags = XBF_DOUBLE_ALLOC;
>
> valuelen = args->rmtvaluelen;
> diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h
> index 28d4ac6fa156..c30c3c253191 100644
> --- a/fs/xfs/libxfs/xfs_da_format.h
> +++ b/fs/xfs/libxfs/xfs_da_format.h
> @@ -914,4 +914,31 @@ struct xfs_parent_name_rec {
> */
> #define XFS_PARENT_DIRENT_NAME_MAX_SIZE (MAXNAMELEN - 1)
>
> +/*
> + * 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.
> + */
> +struct xfs_fsverity_merkle_key {
> + __be64 merkleoff;
Nit: tab here ^ for consistency.
> +};
> +
> +static inline void
> +xfs_fsverity_merkle_key_to_disk(struct xfs_fsverity_merkle_key *key, loff_t pos)
> +{
> + key->merkleoff = cpu_to_be64(pos);
> +}
> +
> +static inline loff_t
> +xfs_fsverity_name_to_block_offset(unsigned char *name)
> +{
> + struct xfs_fsverity_merkle_key key = {
> + .merkleoff = *(__be64 *)name
> + };
> + loff_t offset = be64_to_cpu(key.merkleoff);
> +
> + return offset;
> +}
These helpers should go in xfs_verity.c or wherever they're actually
used. They don't need to be in this header file.
> #endif /* __XFS_DA_FORMAT_H__ */
> diff --git a/fs/xfs/libxfs/xfs_ondisk.h b/fs/xfs/libxfs/xfs_ondisk.h
> index 81885a6a028e..39209943c474 100644
> --- a/fs/xfs/libxfs/xfs_ondisk.h
> +++ b/fs/xfs/libxfs/xfs_ondisk.h
> @@ -194,6 +194,10 @@ xfs_check_ondisk_structs(void)
> XFS_CHECK_VALUE(XFS_DQ_BIGTIME_EXPIRY_MIN << XFS_DQ_BIGTIME_SHIFT, 4);
> XFS_CHECK_VALUE(XFS_DQ_BIGTIME_EXPIRY_MAX << XFS_DQ_BIGTIME_SHIFT,
> 16299260424LL);
> +
> + /* fs-verity descriptor xattr name */
> + XFS_CHECK_VALUE(strlen(XFS_VERITY_DESCRIPTOR_NAME),
> + XFS_VERITY_DESCRIPTOR_NAME_LEN);
strlen works within a macro?
I would've thought this would be:
XFS_CHECK_VALUE(sizeof(XFS_VERITY_DESCRIPTOR_NAME) ==
XFS_VERITY_DESCRIPTOR_NAME_LEN + 1);
> }
>
> #endif /* __XFS_ONDISK_H */
> diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
> index ab46ffb3ac19..d6664e9afa22 100644
> --- a/fs/xfs/xfs_inode.h
> +++ b/fs/xfs/xfs_inode.h
> @@ -348,7 +348,8 @@ static inline bool xfs_inode_has_large_extent_counts(struct xfs_inode *ip)
> * inactivation completes, both flags will be cleared and the inode is a
> * plain old IRECLAIMABLE inode.
> */
> -#define XFS_INACTIVATING (1 << 13)
> +#define XFS_INACTIVATING (1 << 13)
> +#define XFS_IVERITY_CONSTRUCTION (1 << 14) /* merkle tree construction */
This (still) collides with...
> /* Quotacheck is running but inode has not been added to quota counts. */
> #define XFS_IQUOTAUNCHECKED (1 << 14)
...this value here. These are bitmasks; you MUST create a
non-conflicting value here.
You'll also have to update the xfs_iflags_* functions to take an
unsigned long.
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 9f9c35cff9bf..996e6ea91fe1 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -30,6 +30,7 @@
> #include "xfs_filestream.h"
> #include "xfs_quota.h"
> #include "xfs_sysfs.h"
> +#include "xfs_verity.h"
> #include "xfs_ondisk.h"
> #include "xfs_rmap_item.h"
> #include "xfs_refcount_item.h"
> @@ -1520,6 +1521,11 @@ xfs_fs_fill_super(
> sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ;
> #endif
> sb->s_op = &xfs_super_operations;
> +#ifdef CONFIG_FS_VERITY
> + error = fsverity_set_ops(sb, &xfs_verity_ops);
> + if (error)
> + return error;
> +#endif
Isn't fsverity_set_ops a nop if !CONFIG_FS_VERITY?
> /*
> * Delay mount work if the debug hook is set. This is debug
> @@ -1729,6 +1735,10 @@ xfs_fs_fill_super(
> goto out_filestream_unmount;
> }
>
> + if (xfs_has_verity(mp))
> + xfs_alert(mp,
> + "EXPERIMENTAL fs-verity feature in use. Use at your own risk!");
> +
> error = xfs_mountfs(mp);
> if (error)
> goto out_filestream_unmount;
> diff --git a/fs/xfs/xfs_verity.c b/fs/xfs/xfs_verity.c
> new file mode 100644
> index 000000000000..ea31b5bf6214
> --- /dev/null
> +++ b/fs/xfs/xfs_verity.c
> @@ -0,0 +1,355 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
Nit: The SPDX header for C files needs to use C++ comment style, not C.
(This is a really stupid rule decided on by the spdx bureaucrats.)
> +/*
> + * Copyright (C) 2023 Red Hat, Inc.
> + */
> +#include "xfs.h"
> +#include "xfs_shared.h"
> +#include "xfs_format.h"
> +#include "xfs_da_format.h"
> +#include "xfs_da_btree.h"
> +#include "xfs_trans_resv.h"
> +#include "xfs_mount.h"
> +#include "xfs_inode.h"
> +#include "xfs_log_format.h"
> +#include "xfs_attr.h"
> +#include "xfs_verity.h"
> +#include "xfs_bmap_util.h"
> +#include "xfs_log_format.h"
> +#include "xfs_trans.h"
> +#include "xfs_attr_leaf.h"
> +
> +/*
> + * Make fs-verity invalidate verified status of Merkle tree block
> + */
> +static void
> +xfs_verity_put_listent(
> + struct xfs_attr_list_context *context,
> + int flags,
> + unsigned char *name,
> + int namelen,
> + int valuelen)
> +{
> + struct fsverity_blockbuf block = {
> + .offset = xfs_fsverity_name_to_block_offset(name),
> + .size = valuelen,
> + };
> + /*
> + * Verity descriptor is smaller than 1024; verity block min size is
> + * 1024. Exclude verity descriptor
> + */
> + if (valuelen < 1024)
> + return;
As Eric implied elsewhere, shouldn't you be checking here if @name is
/not/ XFS_VERITY_DESCRIPTOR_NAME?
> +
> + fsverity_invalidate_block(VFS_I(context->dp), &block);
> +}
> +
> +/*
> + * Iterate over extended attributes in the bp to invalidate Merkle tree blocks
> + */
> +static int
> +xfs_invalidate_blocks(
> + struct xfs_inode *ip,
> + struct xfs_buf *bp)
> +{
> + struct xfs_attr_list_context context;
> +
> + context.dp = ip;
> + context.resynch = 0;
> + context.buffer = NULL;
> + context.bufsize = 0;
> + context.firstu = 0;
> + context.attr_filter = XFS_ATTR_VERITY;
> + context.put_listent = xfs_verity_put_listent;
> +
> + return xfs_attr3_leaf_list_int(bp, &context);
> +}
Why is it necessary to invalidate every block in the merkle tree?
OH. This is what happens any time that xfs_read_merkle_tree_block
doesn't find a DOUBLE_ALLOC buffer. That's unfortunate, because the
merkle tree could be large enough that a double-alloc'd xattr buffer
gets purged, a subsequent xattr read from the same block nets us a
!double buffer, and then fsverity wants to read the block again.
Does my xblobc rework eliminate the need for all of this?
> +
> +static int
> +xfs_get_verity_descriptor(
> + struct inode *inode,
> + void *buf,
> + size_t buf_size)
> +{
> + struct xfs_inode *ip = XFS_I(inode);
> + int error = 0;
> + struct xfs_da_args args = {
> + .dp = ip,
> + .attr_filter = XFS_ATTR_VERITY,
> + .name = (const uint8_t *)XFS_VERITY_DESCRIPTOR_NAME,
> + .namelen = XFS_VERITY_DESCRIPTOR_NAME_LEN,
> + .value = buf,
> + .valuelen = buf_size,
> + };
> +
> + /*
> + * The fact that (returned attribute size) == (provided buf_size) is
> + * checked by xfs_attr_copy_value() (returns -ERANGE)
Can verity handle ERANGE? Or is that more of an EFSCORRUPTED?
> + */
> + error = xfs_attr_get(&args);
> + if (error)
> + return error;
> +
> + return args.valuelen;
> +}
> +
> +static int
> +xfs_begin_enable_verity(
> + struct file *filp)
> +{
> + struct inode *inode = file_inode(filp);
> + struct xfs_inode *ip = XFS_I(inode);
> + int error = 0;
> +
> + xfs_assert_ilocked(ip, XFS_IOLOCK_EXCL);
Do we need to lock out pagecache invalidations too?
(Can't remember if I already asked that question.)
> +
> + if (IS_DAX(inode))
> + return -EINVAL;
> +
> + if (xfs_iflags_test_and_set(ip, XFS_IVERITY_CONSTRUCTION))
> + return -EBUSY;
> +
> + return error;
> +}
> +
> +static int
> +xfs_drop_merkle_tree(
> + struct xfs_inode *ip,
> + u64 merkle_tree_size,
> + unsigned int tree_blocksize)
> +{
> + struct xfs_fsverity_merkle_key name;
> + int error = 0;
> + u64 offset = 0;
> + struct xfs_da_args args = {
> + .dp = ip,
> + .whichfork = XFS_ATTR_FORK,
> + .attr_filter = XFS_ATTR_VERITY,
> + .op_flags = XFS_DA_OP_REMOVE,
> + .namelen = sizeof(struct xfs_fsverity_merkle_key),
> + /* NULL value make xfs_attr_set remove the attr */
> + .value = NULL,
> + };
> +
> + if (!merkle_tree_size)
> + return 0;
> +
> + args.name = (const uint8_t *)&name.merkleoff;
Can you assign this in the @args initializer?
And shouldn't that be taking the address of the entire struct:
.name = (const uint8_t *)&name,
not just some field within the struct?
> + for (offset = 0; offset < merkle_tree_size; offset += tree_blocksize) {
> + xfs_fsverity_merkle_key_to_disk(&name, offset);
> + error = xfs_attr_set(&args);
> + if (error)
> + return error;
> + }
> +
> + args.name = (const uint8_t *)XFS_VERITY_DESCRIPTOR_NAME;
> + args.namelen = XFS_VERITY_DESCRIPTOR_NAME_LEN;
> + error = xfs_attr_set(&args);
> +
> + return error;
> +}
> +
> +static int
> +xfs_end_enable_verity(
> + struct file *filp,
> + const void *desc,
> + size_t desc_size,
> + u64 merkle_tree_size,
> + unsigned int tree_blocksize)
> +{
> + struct inode *inode = file_inode(filp);
> + struct xfs_inode *ip = XFS_I(inode);
> + struct xfs_mount *mp = ip->i_mount;
> + struct xfs_trans *tp;
> + struct xfs_da_args args = {
> + .dp = ip,
> + .whichfork = XFS_ATTR_FORK,
> + .attr_filter = XFS_ATTR_VERITY,
> + .attr_flags = XATTR_CREATE,
Hmm. How do you recover from the weird situation where DIFLAG2_VERITY
is not set on the file but there /is/ a "vdesc" in the xattrs and you go
to re-enable verity?
Or: Why is it important to fail the ->end_enable operation when we have
all the information we need to reset the verity descriptor?
> + .name = (const uint8_t *)XFS_VERITY_DESCRIPTOR_NAME,
> + .namelen = XFS_VERITY_DESCRIPTOR_NAME_LEN,
> + .value = (void *)desc,
> + .valuelen = desc_size,
> + };
> + int error = 0;
> +
> + xfs_assert_ilocked(ip, XFS_IOLOCK_EXCL);
> +
> + /* fs-verity failed, just cleanup */
> + if (desc == NULL)
> + goto out;
> +
> + error = xfs_attr_set(&args);
> + if (error)
> + goto out;
Case in point: if the system persists this transaction to the log and
crashes at this point, a subsequent re-run of 'fsverity enable' will
fail.
Should the attr_set of the verity descriptor and the setting of
DIFLAG2_VERITY be in the same transaction?
> + /* Set fsverity inode flag */
> + error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_ichange,
> + 0, 0, false, &tp);
> + if (error)
> + goto out;
> +
> + /*
> + * Ensure that we've persisted the verity information before we enable
> + * it on the inode and tell the caller we have sealed the inode.
> + */
> + ip->i_diflags2 |= XFS_DIFLAG2_VERITY;
> +
> + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
> + xfs_trans_set_sync(tp);
Why is it necessary to commit this transaction synchronously? Is this
required by the FS_IOC_ENABLE_VERITY API?
> +
> + error = xfs_trans_commit(tp);
> + xfs_iunlock(ip, XFS_ILOCK_EXCL);
> +
> + if (!error)
> + inode->i_flags |= S_VERITY;
> +
> +out:
> + if (error)
> + WARN_ON_ONCE(xfs_drop_merkle_tree(ip, merkle_tree_size,
> + tree_blocksize));
> +
> + xfs_iflags_clear(ip, XFS_IVERITY_CONSTRUCTION);
> + return error;
> +}
> +
> +static int
> +xfs_read_merkle_tree_block(
> + struct inode *inode,
> + u64 pos,
> + struct fsverity_blockbuf *block,
> + unsigned int log_blocksize,
> + u64 ra_bytes)
> +{
> + struct xfs_inode *ip = XFS_I(inode);
> + struct xfs_fsverity_merkle_key name;
> + int error = 0;
> + struct xfs_da_args args = {
> + .dp = ip,
> + .attr_filter = XFS_ATTR_VERITY,
> + .op_flags = XFS_DA_OP_BUFFER,
> + .namelen = sizeof(struct xfs_fsverity_merkle_key),
> + .valuelen = (1 << log_blocksize),
> + };
> + xfs_fsverity_merkle_key_to_disk(&name, pos);
> + args.name = (const uint8_t *)&name.merkleoff;
.name = (const uint8_t *)&name,
same as above.
> +
> + error = xfs_attr_get(&args);
> + if (error)
> + goto out;
> +
> + if (!args.valuelen)
> + return -ENODATA;
> +
> + block->kaddr = args.value;
> + block->offset = pos;
> + block->size = args.valuelen;
> + block->context = args.bp;
> +
> + /*
> + * Memory barriers are used to force operation ordering of clearing
> + * bitmap in fsverity_invalidate_block() and setting XBF_VERITY_SEEN
> + * flag.
> + *
> + * Multiple threads may execute this code concurrently on the same block.
> + * This is safe because we use memory barriers to ensure that if a
> + * thread sees XBF_VERITY_SEEN, then fsverity bitmap is already up to
> + * date.
> + *
> + * Invalidating block in a bitmap again at worst causes a hash block to
> + * be verified redundantly. That event should be very rare, so it's not
> + * worth using a lock to avoid.
> + */
> + if (!(args.bp->b_flags & XBF_VERITY_SEEN)) {
> + /*
> + * A read memory barrier is needed here to give ACQUIRE
> + * semantics to the above check.
> + */
> + smp_rmb();
> + /*
> + * fs-verity is not aware if buffer was evicted from the memory.
> + * Make fs-verity invalidate verfied status of all blocks in the
> + * buffer.
> + *
> + * Single extended attribute can contain multiple Merkle tree
> + * blocks:
> + * - leaf with inline data -> invalidate all blocks in the leaf
> + * - remote value -> invalidate single block
> + *
> + * For example, leaf on 64k system with 4k/1k filesystem will
> + * contain multiple Merkle tree blocks.
> + *
> + * Only remote value buffers would have XBF_DOUBLE_ALLOC flag
> + */
> + if (args.bp->b_flags & XBF_DOUBLE_ALLOC)
> + fsverity_invalidate_block(inode, block);
> + else {
> + error = xfs_invalidate_blocks(ip, args.bp);
> + if (error)
> + goto out;
> + }
> + }
> +
> + /*
> + * A write memory barrier is needed here to give RELEASE
> + * semantics to the below flag.
> + */
> + smp_wmb();
> + args.bp->b_flags |= XBF_VERITY_SEEN;
Eww. See my version of this in:
https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/log/?h=fsverity-cleanups-6.9_2024-03-07
> + return error;
> +
> +out:
> + kvfree(args.value);
> + if (args.bp)
> + xfs_buf_rele(args.bp);
> + return error;
> +}
> +
> +static int
> +xfs_write_merkle_tree_block(
> + struct inode *inode,
> + const void *buf,
> + u64 pos,
> + unsigned int size)
> +{
> + struct xfs_inode *ip = XFS_I(inode);
> + struct xfs_fsverity_merkle_key name;
> + struct xfs_da_args args = {
> + .dp = ip,
> + .whichfork = XFS_ATTR_FORK,
> + .attr_filter = XFS_ATTR_VERITY,
> + .attr_flags = XATTR_CREATE,
> + .namelen = sizeof(struct xfs_fsverity_merkle_key),
> + .value = (void *)buf,
> + .valuelen = size,
> + };
> +
> + xfs_fsverity_merkle_key_to_disk(&name, pos);
> + args.name = (const uint8_t *)&name.merkleoff;
.name = (const uint8_t *)&name,
same as above.
> +
> + return xfs_attr_set(&args);
> +}
> +
> +static void
> +xfs_drop_block(
> + struct fsverity_blockbuf *block)
> +{
> + struct xfs_buf *bp;
> +
> + ASSERT(block != NULL);
> + bp = (struct xfs_buf *)block->context;
> + ASSERT(bp->b_flags & XBF_VERITY_SEEN);
> +
> + xfs_buf_rele(bp);
> +
> + kunmap_local(block->kaddr);
> +}
> +
> +const struct fsverity_operations xfs_verity_ops = {
> + .begin_enable_verity = &xfs_begin_enable_verity,
> + .end_enable_verity = &xfs_end_enable_verity,
> + .get_verity_descriptor = &xfs_get_verity_descriptor,
> + .read_merkle_tree_block = &xfs_read_merkle_tree_block,
> + .write_merkle_tree_block = &xfs_write_merkle_tree_block,
Not sure why all these function names don't start with "xfs_verity_"?
--D
> + .drop_block = &xfs_drop_block,
> +};
> diff --git a/fs/xfs/xfs_verity.h b/fs/xfs/xfs_verity.h
> new file mode 100644
> index 000000000000..deea15cd3cc5
> --- /dev/null
> +++ b/fs/xfs/xfs_verity.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2022 Red Hat, Inc.
> + */
> +#ifndef __XFS_VERITY_H__
> +#define __XFS_VERITY_H__
> +
> +#include "xfs.h"
> +#include "xfs_da_format.h"
> +#include "xfs_da_btree.h"
> +#include <linux/fsverity.h>
> +
> +#define XFS_VERITY_DESCRIPTOR_NAME "vdesc"
> +#define XFS_VERITY_DESCRIPTOR_NAME_LEN 5
> +
> +static inline bool
> +xfs_verity_merkle_block(
> + struct xfs_da_args *args)
> +{
> + if (!(args->attr_filter & XFS_ATTR_VERITY))
> + return false;
> +
> + if (!(args->op_flags & XFS_DA_OP_BUFFER))
> + return false;
> +
> + return true;
> +}
> +
> +#ifdef CONFIG_FS_VERITY
> +extern const struct fsverity_operations xfs_verity_ops;
> +#endif /* CONFIG_FS_VERITY */
> +
> +#endif /* __XFS_VERITY_H__ */
> --
> 2.42.0
>
>
next prev parent reply other threads:[~2024-03-07 23:10 UTC|newest]
Thread overview: 94+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-04 19:10 [PATCH v5 00/24] fs-verity support for XFS Andrey Albershteyn
2024-03-04 19:10 ` [PATCH v5 01/24] fsverity: remove hash page spin lock Andrey Albershteyn
2024-03-04 19:10 ` [PATCH v5 02/24] xfs: add parent pointer support to attribute code Andrey Albershteyn
2024-03-04 19:10 ` [PATCH v5 03/24] xfs: define parent pointer ondisk extended attribute format Andrey Albershteyn
2024-03-04 19:10 ` [PATCH v5 04/24] xfs: add parent pointer validator functions Andrey Albershteyn
2024-03-04 19:10 ` [PATCH v5 05/24] fs: add FS_XFLAG_VERITY for verity files Andrey Albershteyn
2024-03-04 22:35 ` Eric Biggers
2024-03-07 21:39 ` Darrick J. Wong
2024-03-07 22:06 ` Eric Biggers
2024-03-04 19:10 ` [PATCH v5 06/24] fsverity: pass tree_blocksize to end_enable_verity() Andrey Albershteyn
2024-03-05 0:52 ` Eric Biggers
2024-03-06 16:30 ` Darrick J. Wong
2024-03-07 22:02 ` Eric Biggers
2024-03-08 3:46 ` Darrick J. Wong
2024-03-08 4:40 ` Eric Biggers
2024-03-11 22:38 ` Darrick J. Wong
2024-03-12 15:13 ` David Hildenbrand
2024-03-12 15:33 ` David Hildenbrand
2024-03-12 16:44 ` Darrick J. Wong
2024-03-13 12:29 ` David Hildenbrand
2024-03-13 17:19 ` Darrick J. Wong
2024-03-13 19:10 ` David Hildenbrand
2024-03-13 21:03 ` David Hildenbrand
2024-03-08 21:34 ` Dave Chinner
2024-03-09 16:19 ` Darrick J. Wong
2024-03-04 19:10 ` [PATCH v5 07/24] fsverity: support block-based Merkle tree caching Andrey Albershteyn
2024-03-06 3:56 ` Eric Biggers
2024-03-07 21:54 ` Darrick J. Wong
2024-03-07 22:49 ` Eric Biggers
2024-03-08 3:50 ` Darrick J. Wong
2024-03-09 16:24 ` Darrick J. Wong
2024-03-11 23:22 ` Darrick J. Wong
2024-03-04 19:10 ` [PATCH v5 08/24] fsverity: add per-sb workqueue for post read processing Andrey Albershteyn
2024-03-05 1:08 ` Eric Biggers
2024-03-07 21:58 ` Darrick J. Wong
2024-03-07 22:26 ` Eric Biggers
2024-03-08 3:53 ` Darrick J. Wong
2024-03-07 22:55 ` Dave Chinner
2024-03-04 19:10 ` [PATCH v5 09/24] fsverity: add tracepoints Andrey Albershteyn
2024-03-05 0:33 ` Eric Biggers
2024-03-04 19:10 ` [PATCH v5 10/24] iomap: integrate fs-verity verification into iomap's read path Andrey Albershteyn
2024-03-04 23:39 ` Eric Biggers
2024-03-07 22:06 ` Darrick J. Wong
2024-03-07 22:19 ` Eric Biggers
2024-03-07 23:38 ` Dave Chinner
2024-03-07 23:45 ` Darrick J. Wong
2024-03-08 0:47 ` Dave Chinner
2024-03-07 23:59 ` Eric Biggers
2024-03-08 1:20 ` Dave Chinner
2024-03-08 3:16 ` Eric Biggers
2024-03-08 3:57 ` Darrick J. Wong
2024-03-08 3:22 ` Darrick J. Wong
2024-03-04 19:10 ` [PATCH v5 11/24] xfs: add XBF_VERITY_SEEN xfs_buf flag Andrey Albershteyn
2024-03-07 22:46 ` Darrick J. Wong
2024-03-08 1:59 ` Dave Chinner
2024-03-08 3:31 ` Darrick J. Wong
2024-03-09 16:28 ` Darrick J. Wong
2024-03-11 0:26 ` Dave Chinner
2024-03-11 15:25 ` Darrick J. Wong
2024-03-12 2:43 ` Eric Biggers
2024-03-12 4:15 ` Darrick J. Wong
2024-03-12 2:45 ` Darrick J. Wong
2024-03-12 7:01 ` Dave Chinner
2024-03-12 20:04 ` Darrick J. Wong
2024-03-12 21:45 ` Dave Chinner
2024-03-04 19:10 ` [PATCH v5 12/24] xfs: add XFS_DA_OP_BUFFER to make xfs_attr_get() return buffer Andrey Albershteyn
2024-03-04 19:10 ` [PATCH v5 13/24] xfs: add attribute type for fs-verity Andrey Albershteyn
2024-03-04 19:10 ` [PATCH v5 14/24] xfs: make xfs_buf_get() to take XBF_* flags Andrey Albershteyn
2024-03-04 19:10 ` [PATCH v5 15/24] xfs: add XBF_DOUBLE_ALLOC to increase size of the buffer Andrey Albershteyn
2024-03-04 19:10 ` [PATCH v5 16/24] xfs: add fs-verity ro-compat flag Andrey Albershteyn
2024-03-04 19:10 ` [PATCH v5 17/24] xfs: add inode on-disk VERITY flag Andrey Albershteyn
2024-03-07 22:06 ` Darrick J. Wong
2024-03-04 19:10 ` [PATCH v5 18/24] xfs: initialize fs-verity on file open and cleanup on inode destruction Andrey Albershteyn
2024-03-07 22:09 ` Darrick J. Wong
2024-03-04 19:10 ` [PATCH v5 19/24] xfs: don't allow to enable DAX on fs-verity sealsed inode Andrey Albershteyn
2024-03-07 22:09 ` Darrick J. Wong
2024-03-04 19:10 ` [PATCH v5 20/24] xfs: disable direct read path for fs-verity files Andrey Albershteyn
2024-03-07 22:11 ` Darrick J. Wong
2024-03-12 12:02 ` Andrey Albershteyn
2024-03-12 16:36 ` Darrick J. Wong
2024-03-04 19:10 ` [PATCH v5 21/24] xfs: add fs-verity support Andrey Albershteyn
2024-03-06 4:55 ` Eric Biggers
2024-03-06 5:01 ` Eric Biggers
2024-03-07 23:10 ` Darrick J. Wong [this message]
2024-03-04 19:10 ` [PATCH v5 22/24] xfs: make scrub aware of verity dinode flag Andrey Albershteyn
2024-03-07 22:18 ` Darrick J. Wong
2024-03-12 12:10 ` Andrey Albershteyn
2024-03-12 16:38 ` Darrick J. Wong
2024-03-13 1:35 ` Darrick J. Wong
2024-03-04 19:10 ` [PATCH v5 23/24] xfs: add fs-verity ioctls Andrey Albershteyn
2024-03-07 22:14 ` Darrick J. Wong
2024-03-12 12:42 ` Andrey Albershteyn
2024-03-04 19:10 ` [PATCH v5 24/24] xfs: enable ro-compat fs-verity flag Andrey Albershteyn
2024-03-07 22:16 ` Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240307231038.GC1927156@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=aalbersh@redhat.com \
--cc=chandan.babu@oracle.com \
--cc=ebiggers@kernel.org \
--cc=fsverity@lists.linux.dev \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).