summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuezhang Mo <Yuezhang.Mo@sony.com>2022-10-20 09:27:37 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-03-10 11:34:08 +0300
commit569a77e5b8828fa51160d46ecc6a0d260346adc1 (patch)
treebe63357c8f2f09de205b7b8b40044dbf4eb854d9
parent0c80bef0b7d297ea86e5408fe79c45479e504a26 (diff)
downloadlinux-569a77e5b8828fa51160d46ecc6a0d260346adc1.tar.xz
exfat: fix reporting fs error when reading dir beyond EOF
commit 706fdcac002316893434d753be8cfb549fe1d40d upstream. Since seekdir() does not check whether the position is valid, the position may exceed the size of the directory. We found that for a directory with discontinuous clusters, if the position exceeds the size of the directory and the excess size is greater than or equal to the cluster size, exfat_readdir() will return -EIO, causing a file system error and making the file system unavailable. Reproduce this bug by: seekdir(dir, dir_size + cluster_size); dirent = readdir(dir); The following log will be printed if mount with 'errors=remount-ro'. [11166.712896] exFAT-fs (sdb1): error, invalid access to FAT (entry 0xffffffff) [11166.712905] exFAT-fs (sdb1): Filesystem has been set read-only Fixes: 1e5654de0f51 ("exfat: handle wrong stream entry size in exfat_readdir()") Cc: stable@vger.kernel.org # v5.7+ Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com> Reviewed-by: Andy Wu <Andy.Wu@sony.com> Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com> Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/exfat/dir.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index 0fc08fdcba73..140dba9e0f19 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -102,7 +102,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
clu.dir = ei->hint_bmap.clu;
}
- while (clu_offset > 0) {
+ while (clu_offset > 0 && clu.dir != EXFAT_EOF_CLUSTER) {
if (exfat_get_next_cluster(sb, &(clu.dir)))
return -EIO;