]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: actually fix .. entries that point to inode zero
authorDarrick J. Wong <darrick.wong@oracle.com>
Wed, 23 May 2018 21:30:48 +0000 (16:30 -0500)
committerEric Sandeen <sandeen@redhat.com>
Wed, 23 May 2018 21:30:48 +0000 (16:30 -0500)
If we encounter a directory with an entry that points to inode zero,
we'll crash due to an ASSERT during process_inode_chunk.  This is due to
process_dir2_data not arranging for phase 6 to fix the parent pointer
when '..' -> 0, so do that.  Found via xfs/386 fuzzing bu[1].inumber to
zero.

[sandeen: change "parent pointer" to parent directory for clarity]

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/libxfs_api_defs.h
repair/dir2.c

index fd471de757673714f2b27413805ce4ae3e547805..e519799533a1374c1913e6b620bd9e4364d96597 100644 (file)
@@ -78,6 +78,7 @@
 #define xfs_bmbt_get_all               libxfs_bmbt_get_all
 #define xfs_rtfree_extent              libxfs_rtfree_extent
 #define xfs_verify_rtbno               libxfs_verify_rtbno
+#define xfs_verify_ino                 libxfs_verify_ino
 #define xfs_zero_extent                        libxfs_zero_extent
 
 #define xfs_defer_init                 libxfs_defer_init
index 94dd649b0401ad17c1c1768ed93ad45fb301e72b..e162d2b8e3856fa273e0d148e3c21ea025c7c6c4 100644 (file)
@@ -847,6 +847,23 @@ _("bad .. entry in root directory inode %" PRIu64 ", was %" PRIu64 ": "),
                                        }
                                        *parent = ino;
                                }
+                               /*
+                                * Make sure our parent directory doesn't point
+                                * off into space.
+                                */
+                               if (!junkit &&
+                                   *parent != NULLFSINO &&
+                                   !libxfs_verify_ino(mp, *parent)) {
+                                       do_warn(
+_("bad .. entry in directory inode %" PRIu64 ", was %" PRIu64 ": "),
+                                               ino, *parent);
+                                       if (!no_modify) {
+                                               do_warn(_("correcting\n"));
+                                       } else {
+                                               do_warn(_("would correct\n"));
+                                       }
+                                       *parent = NULLFSINO;
+                               }
                        }
                        /*
                         * Can't fix the directory unless we know which ..