From: Eric Sandeen Date: Thu, 27 Feb 2020 19:21:45 +0000 (-0500) Subject: xfs_repair: fix bad next_unlinked field X-Git-Tag: v5.5.0-rc1~51 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=6bd73d163462f5c0ca78197ec2d8d6f7392974d1;p=thirdparty%2Fxfsprogs-dev.git xfs_repair: fix bad next_unlinked field As of xfsprogs-4.17 we started testing whether the di_next_unlinked field on an inode is valid in the inode verifiers. However, this field is never tested or repaired during inode processing. So if, for example, we had a completely zeroed-out inode, we'd detect and fix the broken magic and version, but the invalid di_next_unlinked field would not be touched, fail the write verifier, and prevent the inode from being properly repaired or even written out. Fix this by checking the di_next_unlinked inode field for validity and clearing it if it is invalid. Reported-by: John Jore Fixes: 2949b4677 ("xfs: don't accept inode buffers with suspicious unlinked chains") Signed-off-by: Eric Sandeen Reviewed-by: Darrick J. Wong Signed-off-by: Eric Sandeen --- diff --git a/repair/dinode.c b/repair/dinode.c index 8af2cb259..929ec8170 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -2272,6 +2272,7 @@ process_dinode_int(xfs_mount_t *mp, const int is_free = 0; const int is_used = 1; blkmap_t *dblkmap = NULL; + xfs_agino_t unlinked_ino; *dirty = *isa_dir = 0; *used = is_used; @@ -2351,6 +2352,23 @@ process_dinode_int(xfs_mount_t *mp, } } + unlinked_ino = be32_to_cpu(dino->di_next_unlinked); + if (!xfs_verify_agino_or_null(mp, agno, unlinked_ino)) { + retval = 1; + if (!uncertain) + do_warn(_("bad next_unlinked 0x%x on inode %" PRIu64 "%c"), + be32_to_cpu(dino->di_next_unlinked), lino, + verify_mode ? '\n' : ','); + if (!verify_mode) { + if (!no_modify) { + do_warn(_(" resetting next_unlinked\n")); + clear_dinode_unlinked(mp, dino); + *dirty = 1; + } else + do_warn(_(" would reset next_unlinked\n")); + } + } + /* * We don't bother checking the CRC here - we cannot guarantee that when * we are called here that the inode has not already been modified in