All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Sandeen <sandeen@sandeen.net>
To: "Darrick J. Wong" <darrick.wong@oracle.com>, sandeen@redhat.com
Cc: linux-xfs@vger.kernel.org
Subject: Re: [PATCH 5/5] xfs_repair: strengthen geometry checks
Date: Fri, 13 Jan 2017 20:13:17 -0600	[thread overview]
Message-ID: <0b7d6af0-d0f0-ee5c-d613-54e03e42fc9e@sandeen.net> (raw)
In-Reply-To: <148419041963.32674.9938209133184119040.stgit@birch.djwong.org>

On 1/11/17 9:06 PM, Darrick J. Wong wrote:
> In xfs_repair, the inodelog, sectlog, and dirblklog values are read
> directly into the xfs_mount structure without any sanity checking by the
> verifier.  This results in xfs_repair segfaulting when those fields have
> ridiculously high values because the pointer arithmetic runs us off the
> end of the metadata buffers.  Therefore, reject the superblock if these
> values are garbage and try to find one of the other ones.
> 
> Also clean up the dblocks checking to use the relevant macros and remove
> a bogus ASSERT that crashes repair when sunit is set but swidth isn't.
> 
> The superblock field fuzzer (xfs/1301) triggers all these segfaults.

ok, thinking out loud below.  Mostly fine but question at the end.

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  repair/sb.c         |   19 ++++++++++++++-----
>  repair/xfs_repair.c |    5 ++++-
>  2 files changed, 18 insertions(+), 6 deletions(-)
> 
> 
> diff --git a/repair/sb.c b/repair/sb.c
> index 004702c..d784420 100644
> --- a/repair/sb.c
> +++ b/repair/sb.c
> @@ -395,21 +395,26 @@ verify_sb(char *sb_buf, xfs_sb_t *sb, int is_primary_sb)
>  	/* sanity check ag count, size fields against data size field */
>  
>  	if (sb->sb_dblocks == 0 ||
> -		sb->sb_dblocks >
> -			((__uint64_t)sb->sb_agcount * sb->sb_agblocks) ||
> -		sb->sb_dblocks <
> -			((__uint64_t)(sb->sb_agcount - 1) * sb->sb_agblocks
> -			+ XFS_MIN_AG_BLOCKS))
> +		sb->sb_dblocks > XFS_MAX_DBLOCKS(sb) ||
> +		sb->sb_dblocks < XFS_MIN_DBLOCKS(sb))

Ok so this is just proper macro replacement, all good.

>  		return(XR_BAD_FS_SIZE_DATA);
>  
>  	if (sb->sb_agblklog != (__uint8_t)libxfs_log2_roundup(sb->sb_agblocks))
>  		return(XR_BAD_FS_SIZE_DATA);
>  
> +	if (sb->sb_inodelog < XFS_DINODE_MIN_LOG ||
> +		sb->sb_inodelog > XFS_DINODE_MAX_LOG ||
> +		sb->sb_inodelog != libxfs_log2_roundup(sb->sb_inodesize))
> +		return XR_BAD_INO_SIZE_DATA;
> +

missing parentheses on the return.  (I kid!)

Ok, we haven't checked out inodesize yet, so if it's wrong, the above
might return XR_BAD_INO_SIZE_DATA even if sb_inodelog is ok.
I suppose that's fine.

hm at some point I wonder if this should more closely match
xfs_mount_validate_sb (or vice versa)

That function does:

            sbp->sb_inodesize != (1 << sbp->sb_inodelog)                ||

which is the reverse I guess.

>  	if (sb->sb_inodesize < XFS_DINODE_MIN_SIZE ||
>  		sb->sb_inodesize > XFS_DINODE_MAX_SIZE ||
>  		sb->sb_inopblock != howmany(sb->sb_blocksize,sb->sb_inodesize))
>  		return(XR_BAD_INO_SIZE_DATA);

Ok, this doesn't cross-check inodesize vs. inodelog, but I guess that's
already done above.

> +	if (sb->sb_blocklog - sb->sb_inodelog != sb->sb_inopblog)
> +		return XR_BAD_INO_SIZE_DATA;
> +

oh yeah that too.

I do kind of wonder if we shouldn't just match that mount code more
closely, and just do

if (sbp->sb_inodesize < XFS_DINODE_MIN_SIZE                     ||
    sbp->sb_inodesize > XFS_DINODE_MAX_SIZE                     ||
    sbp->sb_inodelog < XFS_DINODE_MIN_LOG                       ||
    sbp->sb_inodelog > XFS_DINODE_MAX_LOG                       ||
    sbp->sb_inodesize != (1 << sbp->sb_inodelog)                ||
    sbp->sb_logsunit > XLOG_MAX_RECORD_BSIZE                    ||
    sbp->sb_inopblock != howmany(sbp->sb_blocksize,sbp->sb_inodesize) ||
    (sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog))
	return XR_BAD_INO_SIZE_DATA;

>  	if (xfs_sb_version_hassector(sb))  {
>  
>  		/* check to make sure log sector is legal 2^N, 9 <= N <= 15 */
> @@ -494,6 +499,10 @@ verify_sb(char *sb_buf, xfs_sb_t *sb, int is_primary_sb)
>  			return(XR_BAD_SB_WIDTH);
>  	}
>  
> +	/* Directory block log */
> +	if (sb->sb_dirblklog > XFS_MAX_BLOCKSIZE_LOG)
> +		return XR_BAD_FS_SIZE_DATA;
> +

OK anyway, if any of this fails we go and take a vote from secondaries,
should be fine.

>  	return(XR_OK);
>  }
>  
> diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
> index 5c79fd9..8d4be83 100644
> --- a/repair/xfs_repair.c
> +++ b/repair/xfs_repair.c
> @@ -621,7 +621,10 @@ is_multidisk_filesystem(
>  	if (!sbp->sb_unit)
>  		return false;
>  
> -	ASSERT(sbp->sb_width);
> +	/* Stripe unit but no stripe width?  Something's funny here... */
> +	if (!sbp->sb_width)
> +		return false;
> +

verify_sb did already sanitize this...

        /*
         * verify stripe alignment fields if present
         */
        if (xfs_sb_version_hasdalign(sb)) {
                if ((!sb->sb_unit && sb->sb_width) ||
                    (sb->sb_unit && sb->sb_agblocks % sb->sb_unit))
                        return(XR_BAD_SB_UNIT);
                if ((sb->sb_unit && !sb->sb_width) ||
                    (sb->sb_width && sb->sb_unit && sb->sb_width % sb->sb_unit))
                        return(XR_BAD_SB_WIDTH);
        }

so we do this when we start up:

main
    get_sb
        verify_sb
    ...
    is_multidisk_filesystem

by then it should have been ok, what path did you hit this on?

Seems like we shouldn't be making decisions about "is multidisk"
here, we should be saying "bad superblock" somewhere earlier, no?

I mean, bailing with false is fine I /guess/ but I think the ASSERT
implies that we should have already verified that both or none
are set...

-Eric

>  	return true;
>  }
>  
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

  reply	other threads:[~2017-01-14  2:13 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-12  3:06 [PATCH 0/5] xfsprogs: misc fixes Darrick J. Wong
2017-01-12  3:06 ` [PATCH 1/5] xfs_io: fix the minimum arguments to the reflink command Darrick J. Wong
2017-01-12 13:53   ` Christoph Hellwig
2017-01-12  3:06 ` [PATCH 2/5] xfs_io: fix some documentation problems Darrick J. Wong
2017-01-12 13:53   ` Christoph Hellwig
2017-01-12  3:06 ` [PATCH 3/5] xfs_io: prefix dedupe command error messages consistently Darrick J. Wong
2017-01-12 13:53   ` Christoph Hellwig
2017-01-12  3:06 ` [PATCH 4/5] xfs_db: sanitize geometry on load Darrick J. Wong
2017-01-12 14:34   ` Eric Sandeen
2017-01-12 15:09     ` Brian Foster
2017-01-12 20:41       ` Darrick J. Wong
2017-01-12 20:41   ` [PATCH v2 " Darrick J. Wong
2017-01-12 23:20     ` Eric Sandeen
2017-01-13  0:23       ` Darrick J. Wong
2017-01-13  0:32   ` [PATCH v3 " Darrick J. Wong
2017-01-13 13:35     ` Brian Foster
2017-01-14  2:25       ` Eric Sandeen
2017-01-14  3:44         ` Brian Foster
2017-01-14  3:51           ` Eric Sandeen
2017-01-14 12:53             ` Brian Foster
2017-01-14 14:59               ` Eric Sandeen
2017-01-15 14:10                 ` Brian Foster
2017-01-12  3:06 ` [PATCH 5/5] xfs_repair: strengthen geometry checks Darrick J. Wong
2017-01-14  2:13   ` Eric Sandeen [this message]
2017-01-20 20:06     ` Darrick J. Wong
2017-01-12 19:27 ` [PATCH 6/5] xfs_db: fix the 'source' command when passed as a -c option Darrick J. Wong
2017-01-12 19:34 ` [PATCH 7/5] xfs_repair.8: document dirty log conditions Darrick J. Wong
2017-01-12 19:41   ` Eric Sandeen

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=0b7d6af0-d0f0-ee5c-d613-54e03e42fc9e@sandeen.net \
    --to=sandeen@sandeen.net \
    --cc=darrick.wong@oracle.com \
    --cc=linux-xfs@vger.kernel.org \
    --cc=sandeen@redhat.com \
    /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.