All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: Dave Chinner <david@fromorbit.com>
Cc: linux-xfs@vger.kernel.org
Subject: Re: [PATCH 2/4] xfs: validate inode fork size against fork format
Date: Tue, 3 May 2022 15:55:24 -0700	[thread overview]
Message-ID: <20220503225524.GG8265@magnolia> (raw)
In-Reply-To: <20220502082018.1076561-3-david@fromorbit.com>

On Mon, May 02, 2022 at 06:20:16PM +1000, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> xfs_repair catches fork size/format mismatches, but the in-kernel
> verifier doesn't, leading to null pointer failures when attempting
> to perform operations on the fork. This can occur in the
> xfs_dir_is_empty() where the in-memory fork format does not match
> the size and so the fork data pointer is accessed incorrectly.
> 
> Note: this causes new failures in xfs/348 which is testing mode vs
> ftype mismatches. We now detect a regular file that has been changed
> to a directory or symlink mode as being corrupt because the data
> fork is for a symlink or directory should be in local form when
> there are only 3 bytes of data in the data fork. Hence the inode
> verify for the regular file now fires w/ -EFSCORRUPTED because
> the inode fork format does not match the format the corrupted mode
> says it should be in.
> 
> Signed-off-by: Dave Chinner <dchinner@redhat.com>

/me wonders what the effect this is all going to have on the fuzz vs.
xfs_{scrub,repair} results, but I guess we'll find out in a few weeks.
:P

Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> ---
>  fs/xfs/libxfs/xfs_inode_buf.c | 35 ++++++++++++++++++++++++++---------
>  1 file changed, 26 insertions(+), 9 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
> index 74b82ec80f8e..3b1b63f9d886 100644
> --- a/fs/xfs/libxfs/xfs_inode_buf.c
> +++ b/fs/xfs/libxfs/xfs_inode_buf.c
> @@ -357,21 +357,38 @@ xfs_dinode_verify_fork(
>  {
>  	xfs_extnum_t		di_nextents;
>  	xfs_extnum_t		max_extents;
> +	mode_t			mode = be16_to_cpu(dip->di_mode);
> +	uint32_t		fork_size = XFS_DFORK_SIZE(dip, mp, whichfork);
> +	uint32_t		fork_format = XFS_DFORK_FORMAT(dip, whichfork);
>  
>  	di_nextents = xfs_dfork_nextents(dip, whichfork);
>  
> -	switch (XFS_DFORK_FORMAT(dip, whichfork)) {
> +	/*
> +	 * For fork types that can contain local data, check that the fork
> +	 * format matches the size of local data contained within the fork.
> +	 *
> +	 * For all types, check that when the size says the should be in extent
> +	 * or btree format, the inode isn't claiming it is in local format.
> +	 */
> +	if (whichfork == XFS_DATA_FORK) {
> +		if (S_ISDIR(mode) || S_ISLNK(mode)) {
> +			if (be64_to_cpu(dip->di_size) <= fork_size &&
> +			    fork_format != XFS_DINODE_FMT_LOCAL)
> +				return __this_address;
> +		}
> +
> +		if (be64_to_cpu(dip->di_size) > fork_size &&
> +		    fork_format == XFS_DINODE_FMT_LOCAL)
> +			return __this_address;
> +	}
> +
> +	switch (fork_format) {
>  	case XFS_DINODE_FMT_LOCAL:
>  		/*
> -		 * no local regular files yet
> +		 * No local regular files yet.
>  		 */
> -		if (whichfork == XFS_DATA_FORK) {
> -			if (S_ISREG(be16_to_cpu(dip->di_mode)))
> -				return __this_address;
> -			if (be64_to_cpu(dip->di_size) >
> -					XFS_DFORK_SIZE(dip, mp, whichfork))
> -				return __this_address;
> -		}
> +		if (S_ISREG(mode) && whichfork == XFS_DATA_FORK)
> +			return __this_address;
>  		if (di_nextents)
>  			return __this_address;
>  		break;
> -- 
> 2.35.1
> 

  parent reply	other threads:[~2022-05-03 22:55 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-02  8:20 [PATCH 0/4] xfs: fix random format verification issues Dave Chinner
2022-05-02  8:20 ` [PATCH 1/4] xfs: detect self referencing btree sibling pointers Dave Chinner
2022-05-03 14:53   ` Christoph Hellwig
2022-05-03 21:27     ` Dave Chinner
2022-05-03 22:53   ` Darrick J. Wong
2022-05-03 23:13     ` Dave Chinner
2022-05-06  9:22   ` [xfs] 32678f1513: aim7.jobs-per-min -5.6% regression kernel test robot
2022-05-06  9:22     ` kernel test robot
2022-05-06 21:29     ` Dave Chinner
2022-05-06 21:29       ` Dave Chinner
2022-05-07 11:09       ` [LKP] " Carel Si
2022-05-07 11:09         ` Carel Si
2022-05-09  0:03         ` [LKP] " Dave Chinner
2022-05-09  0:03           ` Dave Chinner
2022-05-02  8:20 ` [PATCH 2/4] xfs: validate inode fork size against fork format Dave Chinner
2022-05-03 14:55   ` Christoph Hellwig
2022-05-03 22:55   ` Darrick J. Wong [this message]
2022-05-02  8:20 ` [PATCH 3/4] xfs: set XFS_FEAT_NLINK correctly Dave Chinner
2022-05-03 14:56   ` Christoph Hellwig
2022-05-03 22:55   ` Darrick J. Wong
2022-05-02  8:20 ` [PATCH 4/4] xfs: validate v5 feature fields Dave Chinner
2022-05-02  9:44   ` kernel test robot
2022-05-02 12:37   ` kernel test robot
2022-05-03 15:00   ` Christoph Hellwig
2022-05-03 21:26     ` Dave Chinner
2022-05-03 22:59   ` Darrick J. Wong
2022-05-03 23:18     ` Dave Chinner
2022-05-03 23:28       ` 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=20220503225524.GG8265@magnolia \
    --to=djwong@kernel.org \
    --cc=david@fromorbit.com \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.