Linux EXT4 FS development
 help / color / mirror / Atom feed
From: Andrey Albershteyn <aalbersh@kernel.org>
To: linux-xfs@vger.kernel.org, fsverity@lists.linux.dev,
	linux-fsdevel@vger.kernel.org, ebiggers@kernel.org
Cc: "Darrick J. Wong" <djwong@kernel.org>,
	hch@lst.de, linux-ext4@vger.kernel.org,
	linux-f2fs-devel@lists.sourceforge.net,
	linux-btrfs@vger.kernel.org,
	Andrey Albershteyn <aalbersh@kernel.org>
Subject: [PATCH v13 21/23] xfs: check and repair the verity inode flag state
Date: Tue, 21 Jul 2026 20:40:58 +0200	[thread overview]
Message-ID: <20260721184346.416657-22-aalbersh@kernel.org> (raw)
In-Reply-To: <20260721184346.416657-1-aalbersh@kernel.org>

From: "Darrick J. Wong" <djwong@kernel.org>

If an inode has the incore verity iflag set, make sure that we can
actually activate fsverity on that inode.  If activation fails due to
a fsverity metadata validation error, clear the flag.  The usage model
for fsverity requires that any program that cares about verity state is
required to call statx/getflags to check that the flag is set after
opening the file, so clearing the flag will not compromise that model.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
---
 fs/xfs/scrub/common.c       | 55 +++++++++++++++++++++++++++++++++++++
 fs/xfs/scrub/common.h       |  2 ++
 fs/xfs/scrub/inode.c        |  7 +++++
 fs/xfs/scrub/inode_repair.c | 36 ++++++++++++++++++++++++
 4 files changed, 100 insertions(+)

diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c
index e5233e31abb7..02b68bf4c512 100644
--- a/fs/xfs/scrub/common.c
+++ b/fs/xfs/scrub/common.c
@@ -45,6 +45,8 @@
 #include "scrub/health.h"
 #include "scrub/tempfile.h"
 
+#include <linux/fsverity.h>
+
 /* Common code for the metadata scrubbers. */
 
 /*
@@ -1754,3 +1756,56 @@ xchk_inode_count_blocks(
 	return xfs_bmap_count_blocks(sc->tp, sc->ip, whichfork, nextents,
 			count);
 }
+
+/*
+ * If this inode has S_VERITY set on it, read the verity info. If the reading
+ * fails with anything other than ENOMEM, the file is corrupt, which we can
+ * detect later with fsverity_active.
+ *
+ * Callers must hold the IOLOCK and must not hold the ILOCK of sc->ip because
+ * activation reads inode data.
+ */
+int
+xchk_inode_setup_verity(
+	struct xfs_scrub	*sc)
+{
+	int			error;
+
+	if (!fsverity_active(VFS_I(sc->ip)))
+		return 0;
+
+	error = fsverity_ensure_verity_info(VFS_I(sc->ip));
+	switch (error) {
+	case 0:
+		/* fsverity is active */
+		break;
+	case -ENODATA:
+	case -EMSGSIZE:
+	case -EINVAL:
+	case -EFSCORRUPTED:
+	case -EFBIG:
+	case -ERANGE:
+	case -EBADMSG:
+		/*
+		 * The nonzero errno codes above are the error codes that can
+		 * be returned from fsverity on metadata validation errors.
+		 */
+		return 0;
+	default:
+		/* runtime errors */
+		return error;
+	}
+
+	return 0;
+}
+
+/*
+ * Is this a verity file that failed to activate?  Callers must have tried to
+ * activate fsverity via xchk_inode_setup_verity.
+ */
+bool
+xchk_inode_verity_broken(
+	struct xfs_inode	*ip)
+{
+	return fsverity_active(VFS_I(ip)) && !fsverity_get_info(VFS_I(ip));
+}
diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h
index 9d627fd50687..3de2b6009a99 100644
--- a/fs/xfs/scrub/common.h
+++ b/fs/xfs/scrub/common.h
@@ -268,6 +268,8 @@ int xchk_inode_is_allocated(struct xfs_scrub *sc, xfs_agino_t agino,
 		bool *inuse);
 int xchk_inode_count_blocks(struct xfs_scrub *sc, int whichfork,
 		xfs_extnum_t *nextents, xfs_filblks_t *count);
+int xchk_inode_setup_verity(struct xfs_scrub *sc);
+bool xchk_inode_verity_broken(struct xfs_inode *ip);
 
 bool xchk_inode_is_dirtree_root(const struct xfs_inode *ip);
 bool xchk_inode_is_sb_rooted(const struct xfs_inode *ip);
diff --git a/fs/xfs/scrub/inode.c b/fs/xfs/scrub/inode.c
index 65b13e311916..d1cdd6b445d0 100644
--- a/fs/xfs/scrub/inode.c
+++ b/fs/xfs/scrub/inode.c
@@ -36,6 +36,10 @@ xchk_prepare_iscrub(
 
 	xchk_ilock(sc, XFS_IOLOCK_EXCL);
 
+	error = xchk_inode_setup_verity(sc);
+	if (error)
+		return error;
+
 	error = xchk_trans_alloc(sc, 0);
 	if (error)
 		return error;
@@ -833,6 +837,9 @@ xchk_inode(
 	if (S_ISREG(VFS_I(sc->ip)->i_mode))
 		xchk_inode_check_reflink_iflag(sc, I_INO(sc->ip));
 
+	if (xchk_inode_verity_broken(sc->ip))
+		xchk_ino_set_corrupt(sc, sc->sm->sm_ino);
+
 	xchk_inode_check_unlinked(sc);
 
 	xchk_inode_xref(sc, I_INO(sc->ip), &di);
diff --git a/fs/xfs/scrub/inode_repair.c b/fs/xfs/scrub/inode_repair.c
index 3ec41c198351..35e93a4b50cd 100644
--- a/fs/xfs/scrub/inode_repair.c
+++ b/fs/xfs/scrub/inode_repair.c
@@ -573,6 +573,8 @@ xrep_dinode_flags(
 		dip->di_nrext64_pad = 0;
 	else if (dip->di_version >= 3)
 		dip->di_v3_pad = 0;
+	if (!xfs_has_verity(mp) || !S_ISREG(mode))
+		flags2 &= ~XFS_DIFLAG2_VERITY;
 
 	if (flags2 & XFS_DIFLAG2_METADATA) {
 		xfs_failaddr_t	fa;
@@ -1617,6 +1619,10 @@ xrep_dinode_core(
 	if (iget_error)
 		return iget_error;
 
+	error = xchk_inode_setup_verity(sc);
+	if (error)
+		return error;
+
 	error = xchk_trans_alloc(sc, 0);
 	if (error)
 		return error;
@@ -2035,6 +2041,27 @@ xrep_inode_unlinked(
 	return 0;
 }
 
+/*
+ * If this file is a fsverity file, xchk_prepare_iscrub or xrep_dinode_core
+ * should have activated it.  If it's still not active, then there's something
+ * wrong with the verity descriptor and we should turn it off.
+ */
+STATIC int
+xrep_inode_verity(
+	struct xfs_scrub	*sc)
+{
+	struct inode		*inode = VFS_I(sc->ip);
+
+	if (xchk_inode_verity_broken(sc->ip)) {
+		sc->ip->i_diflags2 &= ~XFS_DIFLAG2_VERITY;
+		inode_set_flags(inode, 0, S_VERITY);
+
+		xfs_trans_log_inode(sc->tp, sc->ip, XFS_ILOG_CORE);
+	}
+
+	return 0;
+}
+
 /* Repair an inode's fields. */
 int
 xrep_inode(
@@ -2084,6 +2111,15 @@ xrep_inode(
 			return error;
 	}
 
+	/*
+	 * Disable fsverity if it cannot be activated.  Activation failure
+	 * prohibits the file from being opened, so there cannot be another
+	 * program with an open fd to what it thinks is a verity file.
+	 */
+	error = xrep_inode_verity(sc);
+	if (error)
+		return error;
+
 	/* Reconnect incore unlinked list */
 	error = xrep_inode_unlinked(sc);
 	if (error)
-- 
2.54.0


  parent reply	other threads:[~2026-07-21 18:44 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-21 18:40 [PATCH v13 00/23] fs-verity support for XFS with post EOF merkle tree Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 01/23] fsverity: report validation errors through fserror to fsnotify Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 02/23] fsverity: expose ensure_fsverity_info() Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 03/23] fsverity: pass digest size and hash of the all-zeroes block to ->write Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 04/23] fsverity: hoist pagecache_read from f2fs/ext4 to fsverity Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 05/23] fsverity: improve flushing performance of fsverity_fill_zerohash Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 06/23] fsverity: don't allow setting DAX file attribute on fsverity files Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 07/23] fs,fsverity: remove check for fsverity being enabled in setattr_prepare() Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 08/23] fsverity: hoist statx reporting of fs-verity flag Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 09/23] xfs: introduce fsverity on-disk changes Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 10/23] xfs: don't allow to enable DAX on fs-verity sealed inode Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 11/23] xfs: disable direct read path for fs-verity files Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 12/23] xfs: don't report dio_mem_align and dio_offset_align for fsverity files Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 13/23] xfs: handle fsverity I/O in write/read path Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 14/23] xfs: always prioritize fsverity metadata ioends in ioend completion Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 15/23] xfs: use read ioend for fsverity data verification Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 16/23] xfs: add fs-verity support Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 17/23] xfs: remove unwritten extents after preallocations in fsverity metadata Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 18/23] xfs: initialize fs-verity on file open Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 19/23] xfs: add fs-verity ioctls Andrey Albershteyn
2026-07-21 18:40 ` [PATCH v13 20/23] xfs: advertise fs-verity being available on filesystem Andrey Albershteyn
2026-07-21 18:40 ` Andrey Albershteyn [this message]
2026-07-21 18:40 ` [PATCH v13 22/23] xfs: introduce health state for corrupted fsverity metadata Andrey Albershteyn
2026-07-21 18:41 ` [PATCH v13 23/23] xfs: enable ro-compat fs-verity flag Andrey Albershteyn

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=20260721184346.416657-22-aalbersh@kernel.org \
    --to=aalbersh@kernel.org \
    --cc=djwong@kernel.org \
    --cc=ebiggers@kernel.org \
    --cc=fsverity@lists.linux.dev \
    --cc=hch@lst.de \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --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