All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gao Xiang <hsiangkao@redhat.com>
To: Brian Foster <bfoster@redhat.com>
Cc: linux-xfs@vger.kernel.org, "Darrick J . Wong" <darrick.wong@oracle.com>
Subject: Re: [PATCH v3 1/2] xfs: avoid LR buffer overrun due to crafted h_{len,size}
Date: Fri, 4 Sep 2020 20:46:34 +0800	[thread overview]
Message-ID: <20200904124634.GA28752@xiangao.remote.csb> (raw)
In-Reply-To: <20200904112529.GB529978@bfoster>

Hi Brian,

On Fri, Sep 04, 2020 at 07:25:29AM -0400, Brian Foster wrote:
> On Fri, Sep 04, 2020 at 04:25:15PM +0800, Gao Xiang wrote:

...

> > @@ -2904,9 +2904,10 @@ STATIC int
> >  xlog_valid_rec_header(
> >  	struct xlog		*log,
> >  	struct xlog_rec_header	*rhead,
> > -	xfs_daddr_t		blkno)
> > +	xfs_daddr_t		blkno,
> > +	int			bufsize)
> >  {
> > -	int			hlen;
> > +	int			hlen, hsize = XLOG_BIG_RECORD_BSIZE;
> >  
> >  	if (XFS_IS_CORRUPT(log->l_mp,
> >  			   rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM)))
> > @@ -2920,10 +2921,22 @@ xlog_valid_rec_header(
> >  		return -EFSCORRUPTED;
> >  	}
> >  
> > -	/* LR body must have data or it wouldn't have been written */
> > +	/*
> > +	 * LR body must have data (or it wouldn't have been written) and
> > +	 * h_len must not be greater than h_size with one exception (see
> > +	 * comments in xlog_do_recovery_pass()).
> > +	 */
> 
> I wouldn't mention the exceptional case at all here since I think it
> just adds confusion. It's an unfortunate wart with mkfs that requires a
> kernel workaround, and I think it's better to keep it one place. I.e.,
> should it ever be removed, I find it unlikely somebody will notice this
> comment and fix it up accordingly.

Thanks for your review.

ok, if I understand correctly, will remove this "with one exception
(see comments..." expression. Please kindly correct me if I
misunderstand.

> 
> > +
> > +	if (XFS_IS_CORRUPT(log->l_mp, hlen <= 0 || hlen > hsize))
> >  		return -EFSCORRUPTED;
> > +
> > +	if (bufsize && XFS_IS_CORRUPT(log->l_mp, bufsize < hsize))
> > +		return -EFSCORRUPTED;
> 
> Please do something like the following so the full corruption check
> logic is readable:
> 
> 	if (XFS_IS_CORRUPT(..., bufsize && hsize > bufsize))
> 		return -EFSCORRUPTED;

That is good idea, will update this as well. 

>

...

> >  		rhead = (xlog_rec_header_t *)offset;
> > -		error = xlog_valid_rec_header(log, rhead, tail_blk);
> > -		if (error)
> > -			goto bread_err1;
> 
> This technically defers broader corruption checks (i.e., magic number,
> etc.) until after functional code starts using other fields below. I
> don't think we should remove this.
> 

I'm trying to combine this with the following part...(see below...)

> >  
> >  		/*
> >  		 * xfsprogs has a bug where record length is based on lsunit but
> > @@ -3001,21 +3011,19 @@ xlog_do_recovery_pass(
> >  		 */
> >  		h_size = be32_to_cpu(rhead->h_size);
> >  		h_len = be32_to_cpu(rhead->h_len);
> > -		if (h_len > h_size) {
> > -			if (h_len <= log->l_mp->m_logbsize &&
> > -			    be32_to_cpu(rhead->h_num_logops) == 1) {
> > -				xfs_warn(log->l_mp,
> > +		if (h_len > h_size && h_len <= log->l_mp->m_logbsize &&
> > +		    rhead->h_num_logops == cpu_to_be32(1)) {
> > +			xfs_warn(log->l_mp,
> >  		"invalid iclog size (%d bytes), using lsunit (%d bytes)",
> > -					 h_size, log->l_mp->m_logbsize);
> > -				h_size = log->l_mp->m_logbsize;
> > -			} else {
> > -				XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW,
> > -						log->l_mp);
> > -				error = -EFSCORRUPTED;
> > -				goto bread_err1;
> > -			}
> > +				 h_size, log->l_mp->m_logbsize);
> > +			h_size = log->l_mp->m_logbsize;
> > +			rhead->h_size = cpu_to_be32(h_size);
> 
> I don't think we should update rhead like this, particularly in a rare
> and exclusive case. This structure should reflect what is on disk.
> 
> All in all, I think this patch should be much more focused:
> 
> 1.) Add the bufsize parameter and associated corruption check to
> xlog_valid_rec_header().
> 2.) Pass the related value from the existing calls.
> 3.) (Optional) If there's reason to revalidate after executing the mkfs
> workaround, add a second call within the branch that implements the
> h_size workaround.
> 

I moved workaround code to xlog_valid_rec_header() at first is
because in xlog_valid_rec_header() actually it has 2 individual
checks now:

1) check rhead->h_len vs rhead->h_size for each individual log record;
2) check rhead->h_size vs the unique allocated buffer size passed in
   for each record (since each log record has one stored h_size,
   even though there are not used later according to the current
   logic of xlog_do_recovery_pass).

if any of the conditions above is not satisfied, xlog_valid_rec_header()
will make fs corrupted immediately, so I tried 2 ways up to now:

 - (v1,v2) fold in workaround case into xlog_valid_rec_header()
 - (v3) rearrange workaround and xlog_valid_rec_header() order in
        xlog_do_recovery_pass() and modify rhead->h_size to the
        workaround h_size before xlog_valid_rec_header() validation
        so xlog_valid_rec_header() will work as expected since it
        has two individual checks as mentioned above.

If there is some better way, kindly let me know :) and I'd like to
hear other folks about this in advance as well.... so I can go
forward since this part is a bit tricky for now.

> Also, please test the workaround case to make sure it still works as
> expected (if you haven't already).

ok, will double confirm this, thanks!

Thanks,
Gao Xiang

> 
> Brian
>
 


  reply	other threads:[~2020-09-04 12:47 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-04  8:25 [PATCH 0/2] xfs: random patches on log recovery Gao Xiang
2020-09-04  8:25 ` [PATCH v3 1/2] xfs: avoid LR buffer overrun due to crafted h_{len,size} Gao Xiang
2020-09-04 11:25   ` Brian Foster
2020-09-04 12:46     ` Gao Xiang [this message]
2020-09-04 13:37       ` Brian Foster
2020-09-04 15:01         ` Gao Xiang
2020-09-04 16:31           ` Brian Foster
2020-09-04  8:25 ` [PATCH v2 2/2] xfs: clean up calculation of LR header blocks Gao Xiang
2020-09-04 11:25   ` Brian Foster
2020-09-04 12:59     ` Gao Xiang
2020-09-04 13:37       ` Brian Foster
2020-09-04 15:07         ` Gao Xiang
2020-09-04 16:32           ` Brian Foster

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=20200904124634.GA28752@xiangao.remote.csb \
    --to=hsiangkao@redhat.com \
    --cc=bfoster@redhat.com \
    --cc=darrick.wong@oracle.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.