]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: fully check the parent handle when it points to the rootdir
authorDarrick J. Wong <djwong@kernel.org>
Tue, 14 Jul 2026 06:06:59 +0000 (23:06 -0700)
committerCarlos Maiolino <cem@kernel.org>
Tue, 14 Jul 2026 09:01:47 +0000 (11:01 +0200)
LOLLM noticed that the directory tree path checking declares the path to
be ok if the inumber in the parent pointer reaches the root directory.
Unfortunately, it neglects to check that the generation is correct.  Fix
that by moving the generation check up.

Cc: stable@vger.kernel.org # v6.10
Fixes: 928b721a11789a ("xfs: teach online scrub to find directory tree structure problems")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
fs/xfs/scrub/dirtree.c

index c6a210f7508fc2accda89cbea9818a7e10d12a8f..b2cf6e5439d915f87b91cb1583312275726e134e 100644 (file)
@@ -383,6 +383,14 @@ xchk_dirpath_step_up(
                goto out_scanlock;
        }
 
+       /* The handle encoded in the parent pointer must match. */
+       if (VFS_I(dp)->i_generation != be32_to_cpu(dl->pptr_rec.p_gen)) {
+               trace_xchk_dirpath_badgen(dl->sc, dp, path->path_nr,
+                               path->nr_steps, &dl->xname, &dl->pptr_rec);
+               error = -EFSCORRUPTED;
+               goto out_scanlock;
+       }
+
        /* We've reached the root directory; the path is ok. */
        if (parent_ino == dl->root_ino) {
                xchk_dirpath_set_outcome(dl, path, XCHK_DIRPATH_OK);
@@ -411,14 +419,6 @@ xchk_dirpath_step_up(
                goto out_scanlock;
        }
 
-       /* The handle encoded in the parent pointer must match. */
-       if (VFS_I(dp)->i_generation != be32_to_cpu(dl->pptr_rec.p_gen)) {
-               trace_xchk_dirpath_badgen(dl->sc, dp, path->path_nr,
-                               path->nr_steps, &dl->xname, &dl->pptr_rec);
-               error = -EFSCORRUPTED;
-               goto out_scanlock;
-       }
-
        /* Parent pointer must point up to a directory. */
        if (!S_ISDIR(VFS_I(dp)->i_mode)) {
                trace_xchk_dirpath_nondir_parent(dl->sc, dp, path->path_nr,