On Mon, Feb 10, 2020 at 09:42:28AM -0600, Eric Sandeen wrote: > 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 <john@xxxxxxx> > Fixes: 2949b4677 ("xfs: don't accept inode buffers with suspicious unlinked chains") > Signed-off-by: Eric Sandeen <sandeen@xxxxxxxxxx> Seems reasonable, Reviewed-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> --D > --- > > diff --git a/repair/dinode.c b/repair/dinode.c > index 8af2cb25..c5d2f350 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"), > + (__s32)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 >