diff mbox series

[2/7] xfs_repair: fix error in process_sf_dir2_fixi8

Message ID 159950112994.567790.6177947698105660609.stgit@magnolia
State Accepted
Headers show
Series xfs_repair: more fuzzer fixes | expand

Commit Message

Darrick J. Wong Sept. 7, 2020, 5:52 p.m. UTC
From: Darrick J. Wong <darrick.wong@oracle.com>

The goal of process_sf_dir2_fixi8 is to convert an i8 shortform
directory into a (shorter) i4 shortform directory.  It achieves this by
duplicating the old sf directory contents (as oldsfp), zeroing i8count
in the caller's directory buffer (i.e. newsfp/sfp), and reinitializing
the new directory with the old directory's entries.

Unfortunately, it copies the parent pointer from sfp (the buffer we've
already started changing), not oldsfp.  This leads to directory
corruption since at that point we zeroed i8count, which means that we
save only the upper four bytes from the parent pointer entry.

This was found by fuzzing u3.sfdir3.hdr.i8count = ones in xfs/384.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 repair/dir2.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Christoph Hellwig Sept. 8, 2020, 2:46 p.m. UTC | #1
On Mon, Sep 07, 2020 at 10:52:10AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> The goal of process_sf_dir2_fixi8 is to convert an i8 shortform
> directory into a (shorter) i4 shortform directory.  It achieves this by
> duplicating the old sf directory contents (as oldsfp), zeroing i8count
> in the caller's directory buffer (i.e. newsfp/sfp), and reinitializing
> the new directory with the old directory's entries.
> 
> Unfortunately, it copies the parent pointer from sfp (the buffer we've
> already started changing), not oldsfp.  This leads to directory
> corruption since at that point we zeroed i8count, which means that we
> save only the upper four bytes from the parent pointer entry.
> 
> This was found by fuzzing u3.sfdir3.hdr.i8count = ones in xfs/384.

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>
diff mbox series

Patch

diff --git a/repair/dir2.c b/repair/dir2.c
index 95e8c2009d1f..eabdb4f2d497 100644
--- a/repair/dir2.c
+++ b/repair/dir2.c
@@ -84,7 +84,7 @@  process_sf_dir2_fixi8(
 	memmove(oldsfp, newsfp, oldsize);
 	newsfp->count = oldsfp->count;
 	newsfp->i8count = 0;
-	ino = libxfs_dir2_sf_get_parent_ino(sfp);
+	ino = libxfs_dir2_sf_get_parent_ino(oldsfp);
 	libxfs_dir2_sf_put_parent_ino(newsfp, ino);
 	oldsfep = xfs_dir2_sf_firstentry(oldsfp);
 	newsfep = xfs_dir2_sf_firstentry(newsfp);