6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 9f84792b40d0c96833341602144574bf0bd14a6a upstream.
LOLLM noticed that xrep_dir_recover_data can spin forever if it
encounters an unused dirent that claims to have length zero. Fix that,
and prevent the same thing from happening with a zero-length entry.
Cc: stable@vger.kernel.org # v6.10
Fixes: b1991ee3e7cf85 ("xfs: online repair of directories")
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/dir_repair.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- a/fs/xfs/scrub/dir_repair.c
+++ b/fs/xfs/scrub/dir_repair.c
@@ -478,18 +478,24 @@ xrep_dir_recover_data(
while (offset < end) {
struct xfs_dir2_data_unused *dup = bp->b_addr + offset;
struct xfs_dir2_data_entry *dep = bp->b_addr + offset;
+ unsigned int advance;
if (xchk_should_terminate(rd->sc, &error))
return error;
/* Skip unused entries. */
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
+ if (!dup->length)
+ break;
offset += be16_to_cpu(dup->length);
continue;
}
/* Don't walk off the end of the block. */
- offset += xfs_dir2_data_entsize(rd->sc->mp, dep->namelen);
+ advance = xfs_dir2_data_entsize(rd->sc->mp, dep->namelen);
+ if (!advance)
+ break;
+ offset += advance;
if (offset > end)
break;