Linux-XFS Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH] xfs: add agf freeblocks verify in xfs_agf_verify
@ 2020-02-13  9:53 Zheng Bin
  2020-02-13 13:37 ` Eric Sandeen
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Zheng Bin @ 2020-02-13  9:53 UTC (permalink / raw)
  To: david, darrick.wong, sandeen, linux-xfs; +Cc: renxudong1

We recently used fuzz(hydra) to test XFS and automatically generate
tmp.img(XFS v5 format, but some metadata is wrong)

Test as follows:
mount tmp.img tmpdir
cp file1M tmpdir
sync

tmpdir/file1M size is 1M, but its data can not sync to disk.

This is because tmp.img has some problems, using xfs_repair detect
information as follows:

agf_freeblks 0, counted 3224 in ag 0
agf_longest 536874136, counted 3224 in ag 0
sb_fdblocks 613, counted 3228

Add these agf freeblocks checks:
1. agf_longest < agf_freeblks
2. agf_freeblks < sb_fdblocks

Signed-off-by: Zheng Bin <zhengbin13@huawei.com>
Signed-off-by: Ren Xudong <renxudong1@huawei.com>
---
 fs/xfs/libxfs/xfs_alloc.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index d8053bc..0f4b4d1 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -2858,6 +2858,10 @@ xfs_agf_verify(
 	      be32_to_cpu(agf->agf_flcount) <= xfs_agfl_size(mp)))
 		return __this_address;

+	if (be32_to_cpu(agf->agf_freeblks) < be32_to_cpu(agf->agf_longest) ||
+	    be32_to_cpu(agf->agf_freeblks) >= mp->m_sb.sb_fdblocks)
+		return __this_address;
+
 	if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 ||
 	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 ||
 	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS ||
--
2.7.4


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] xfs: add agf freeblocks verify in xfs_agf_verify
  2020-02-13  9:53 [PATCH] xfs: add agf freeblocks verify in xfs_agf_verify Zheng Bin
@ 2020-02-13 13:37 ` Eric Sandeen
  2020-02-13 17:44 ` Darrick J. Wong
  2020-02-13 20:55 ` Dave Chinner
  2 siblings, 0 replies; 4+ messages in thread
From: Eric Sandeen @ 2020-02-13 13:37 UTC (permalink / raw)
  To: Zheng Bin, david, darrick.wong, sandeen, linux-xfs; +Cc: renxudong1

On 2/13/20 3:53 AM, Zheng Bin wrote:
> We recently used fuzz(hydra) to test XFS and automatically generate
> tmp.img(XFS v5 format, but some metadata is wrong)
> 
> Test as follows:
> mount tmp.img tmpdir
> cp file1M tmpdir
> sync

I would leave this part out of the change log, because it is not a
useful testcase for anyone who does not have your test.img.

> tmpdir/file1M size is 1M, but its data can not sync to disk.
> 
> This is because tmp.img has some problems, using xfs_repair detect
> information as follows:
> 
> agf_freeblks 0, counted 3224 in ag 0
> agf_longest 536874136, counted 3224 in ag 0
> sb_fdblocks 613, counted 3228
> 
> Add these agf freeblocks checks:
> 1. agf_longest < agf_freeblks
> 2. agf_freeblks < sb_fdblocks

This left out the 2nd check Dave suggested, that freeblocks is
less than the number of blocks in the AG, i.e.

b) agf_freeblks < sb_dblocks / sb_agcount

(and yes, it must special-case the last AG which may be smaller - see
xfs_ag_block_count())

-Eric


> Signed-off-by: Zheng Bin <zhengbin13@huawei.com>
> Signed-off-by: Ren Xudong <renxudong1@huawei.com>
> ---
>  fs/xfs/libxfs/xfs_alloc.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
> index d8053bc..0f4b4d1 100644
> --- a/fs/xfs/libxfs/xfs_alloc.c
> +++ b/fs/xfs/libxfs/xfs_alloc.c
> @@ -2858,6 +2858,10 @@ xfs_agf_verify(
>  	      be32_to_cpu(agf->agf_flcount) <= xfs_agfl_size(mp)))
>  		return __this_address;
> 
> +	if (be32_to_cpu(agf->agf_freeblks) < be32_to_cpu(agf->agf_longest) ||
> +	    be32_to_cpu(agf->agf_freeblks) >= mp->m_sb.sb_fdblocks)
> +		return __this_address;
> +
>  	if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 ||
>  	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 ||
>  	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS ||
> --
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] xfs: add agf freeblocks verify in xfs_agf_verify
  2020-02-13  9:53 [PATCH] xfs: add agf freeblocks verify in xfs_agf_verify Zheng Bin
  2020-02-13 13:37 ` Eric Sandeen
@ 2020-02-13 17:44 ` Darrick J. Wong
  2020-02-13 20:55 ` Dave Chinner
  2 siblings, 0 replies; 4+ messages in thread
From: Darrick J. Wong @ 2020-02-13 17:44 UTC (permalink / raw)
  To: Zheng Bin; +Cc: david, sandeen, linux-xfs, renxudong1

On Thu, Feb 13, 2020 at 05:53:59PM +0800, Zheng Bin wrote:
> We recently used fuzz(hydra) to test XFS and automatically generate
> tmp.img(XFS v5 format, but some metadata is wrong)
> 
> Test as follows:
> mount tmp.img tmpdir
> cp file1M tmpdir
> sync
> 
> tmpdir/file1M size is 1M, but its data can not sync to disk.
> 
> This is because tmp.img has some problems, using xfs_repair detect
> information as follows:
> 
> agf_freeblks 0, counted 3224 in ag 0
> agf_longest 536874136, counted 3224 in ag 0
> sb_fdblocks 613, counted 3228
> 
> Add these agf freeblocks checks:
> 1. agf_longest < agf_freeblks
> 2. agf_freeblks < sb_fdblocks

Uh... what problem did you encounter?  Did block allocation loop
forever?  Did errors come pouring out of dmesg?  Did other strange
behaviors erupt?  What is the smallest number of steps needed to go from
a fresh format to ... whatever went wrong here?

That's what this commit message ought to capture. :)

--D

> Signed-off-by: Zheng Bin <zhengbin13@huawei.com>
> Signed-off-by: Ren Xudong <renxudong1@huawei.com>
> ---
>  fs/xfs/libxfs/xfs_alloc.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
> index d8053bc..0f4b4d1 100644
> --- a/fs/xfs/libxfs/xfs_alloc.c
> +++ b/fs/xfs/libxfs/xfs_alloc.c
> @@ -2858,6 +2858,10 @@ xfs_agf_verify(
>  	      be32_to_cpu(agf->agf_flcount) <= xfs_agfl_size(mp)))
>  		return __this_address;
> 
> +	if (be32_to_cpu(agf->agf_freeblks) < be32_to_cpu(agf->agf_longest) ||
> +	    be32_to_cpu(agf->agf_freeblks) >= mp->m_sb.sb_fdblocks)
> +		return __this_address;
> +
>  	if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 ||
>  	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 ||
>  	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS ||
> --
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] xfs: add agf freeblocks verify in xfs_agf_verify
  2020-02-13  9:53 [PATCH] xfs: add agf freeblocks verify in xfs_agf_verify Zheng Bin
  2020-02-13 13:37 ` Eric Sandeen
  2020-02-13 17:44 ` Darrick J. Wong
@ 2020-02-13 20:55 ` Dave Chinner
  2 siblings, 0 replies; 4+ messages in thread
From: Dave Chinner @ 2020-02-13 20:55 UTC (permalink / raw)
  To: Zheng Bin; +Cc: darrick.wong, sandeen, linux-xfs, renxudong1

On Thu, Feb 13, 2020 at 05:53:59PM +0800, Zheng Bin wrote:
> We recently used fuzz(hydra) to test XFS and automatically generate
> tmp.img(XFS v5 format, but some metadata is wrong)
> 
> Test as follows:
> mount tmp.img tmpdir
> cp file1M tmpdir
> sync
> 
> tmpdir/file1M size is 1M, but its data can not sync to disk.
> 
> This is because tmp.img has some problems, using xfs_repair detect
> information as follows:
> 
> agf_freeblks 0, counted 3224 in ag 0
> agf_longest 536874136, counted 3224 in ag 0
> sb_fdblocks 613, counted 3228
> 
> Add these agf freeblocks checks:
> 1. agf_longest < agf_freeblks
> 2. agf_freeblks < sb_fdblocks

Did you audit the other fields in the AGF to see if they were
adequately bounds checked by xfs_agf_verify()?

A quick look at struct xfs_agf and xfs_agf_verify() indicates that
agf_length, agf_rmap_blocks and agf_refcount_blocks are not bounds
checked, either. And agf_spare64 and agf_spare2 are not checked for
being zero....

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, back to index

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-13  9:53 [PATCH] xfs: add agf freeblocks verify in xfs_agf_verify Zheng Bin
2020-02-13 13:37 ` Eric Sandeen
2020-02-13 17:44 ` Darrick J. Wong
2020-02-13 20:55 ` Dave Chinner

Linux-XFS Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-xfs/0 linux-xfs/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-xfs linux-xfs/ https://lore.kernel.org/linux-xfs \
		linux-xfs@vger.kernel.org
	public-inbox-index linux-xfs

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-xfs


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git