]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
exfat: fix the infinite loop in __exfat_free_cluster()
authorYuezhang Mo <Yuezhang.Mo@sony.com>
Mon, 16 Dec 2024 05:39:42 +0000 (13:39 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Jan 2025 12:34:37 +0000 (13:34 +0100)
[ Upstream commit a5324b3a488d883aa2d42f72260054e87d0940a0 ]

In __exfat_free_cluster(), the cluster chain is traversed until the
EOF cluster. If the cluster chain includes a loop due to file system
corruption, the EOF cluster cannot be traversed, resulting in an
infinite loop.

This commit uses the total number of clusters to prevent this infinite
loop.

Reported-by: syzbot+1de5a37cb85a2d536330@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1de5a37cb85a2d536330
Tested-by: syzbot+1de5a37cb85a2d536330@syzkaller.appspotmail.com
Fixes: 31023864e67a ("exfat: add fat entry operations")
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/exfat/fatent.c

index 41ae4cce1f4203c1d8ecd6e4bd92e23fc42f7366..fe007ae2f23c82eef3c620d07b0ecd787ef890e3 100644 (file)
@@ -216,6 +216,16 @@ static int __exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain
 
                        if (err)
                                goto dec_used_clus;
+
+                       if (num_clusters >= sbi->num_clusters - EXFAT_FIRST_CLUSTER) {
+                               /*
+                                * The cluster chain includes a loop, scan the
+                                * bitmap to get the number of used clusters.
+                                */
+                               exfat_count_used_clusters(sb, &sbi->used_clusters);
+
+                               return 0;
+                       }
                } while (clu != EXFAT_EOF_CLUSTER);
        }