diff mbox series

[v1] exfat: fix the infinite loop in exfat_readdir()

Message ID PUZPR04MB6316E933E479EA23F39EC2F0813B2@PUZPR04MB6316.apcprd04.prod.outlook.com (mailing list archive)
State New
Headers show
Series [v1] exfat: fix the infinite loop in exfat_readdir() | expand

Commit Message

Yuezhang.Mo@sony.com Dec. 16, 2024, 3:37 a.m. UTC
If the file system is corrupted so that a cluster is linked to
itself in the cluster chain, and there is an unused directory
entry in the cluster, 'dentry' will not be incremented, causing
condition 'dentry < max_dentries' unable to prevent an infinite
loop.

This infinite loop causes s_lock not to be released, and other
tasks will hang, such as exfat_sync_fs().

This commit stops traversing the cluster chain when there is unused
directory entry in the cluster to avoid this infinite loop.

Reported-by: syzbot+205c2644abdff9d3f9fc@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=205c2644abdff9d3f9fc
Tested-by: syzbot+205c2644abdff9d3f9fc@syzkaller.appspotmail.com
Fixes: ca06197382bd ("exfat: add directory operations")
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
---
 fs/exfat/dir.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Namjae Jeon Dec. 18, 2024, 4:21 a.m. UTC | #1
On Mon, Dec 16, 2024 at 12:37 PM Yuezhang.Mo@sony.com
<Yuezhang.Mo@sony.com> wrote:
>
> If the file system is corrupted so that a cluster is linked to
> itself in the cluster chain, and there is an unused directory
> entry in the cluster, 'dentry' will not be incremented, causing
> condition 'dentry < max_dentries' unable to prevent an infinite
> loop.
>
> This infinite loop causes s_lock not to be released, and other
> tasks will hang, such as exfat_sync_fs().
>
> This commit stops traversing the cluster chain when there is unused
> directory entry in the cluster to avoid this infinite loop.
>
> Reported-by: syzbot+205c2644abdff9d3f9fc@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=205c2644abdff9d3f9fc
> Tested-by: syzbot+205c2644abdff9d3f9fc@syzkaller.appspotmail.com
> Fixes: ca06197382bd ("exfat: add directory operations")
> Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Applied it to #dev.
Thanks!
diff mbox series

Patch

From 2ba96e6e4923f0ad0d1bbcc077e887d5d7031bc0 Mon Sep 17 00:00:00 2001
From: Yuezhang Mo <Yuezhang.Mo@sony.com>
Date: Fri, 13 Dec 2024 13:08:37 +0800
Subject: [PATCH v1] exfat: fix the infinite loop in exfat_readdir()

If the file system is corrupted so that a cluster is linked to
itself in the cluster chain, and there is an unused directory
entry in the cluster, 'dentry' will not be incremented, causing
condition 'dentry < max_dentries' unable to prevent an infinite
loop.

This infinite loop causes s_lock not to be released, and other
tasks will hang, such as exfat_sync_fs().

This commit stops traversing the cluster chain when there is unused
directory entry in the cluster to avoid this infinite loop.

Reported-by: syzbot+205c2644abdff9d3f9fc@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=205c2644abdff9d3f9fc
Tested-by: syzbot+205c2644abdff9d3f9fc@syzkaller.appspotmail.com
Fixes: ca06197382bd ("exfat: add directory operations")
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
---
 fs/exfat/dir.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index fe0a9b8a0cd0..3103b932b674 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -122,7 +122,7 @@  static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
 			type = exfat_get_entry_type(ep);
 			if (type == TYPE_UNUSED) {
 				brelse(bh);
-				break;
+				goto out;
 			}
 
 			if (type != TYPE_FILE && type != TYPE_DIR) {
@@ -170,6 +170,7 @@  static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
 		}
 	}
 
+out:
 	dir_entry->namebuf.lfn[0] = '\0';
 	*cpos = EXFAT_DEN_TO_B(dentry);
 	return 0;
-- 
2.43.0