2022-12-26 07:42:38

by [email protected]

[permalink] [raw]
Subject: [PATCH v1] exfat: fix reporting fs error when reading dir beyond EOF

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()")

Signed-off-by: Yuezhang Mo <[email protected]>
Reviewed-by: Andy Wu <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
---
fs/exfat/dir.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index 1122bee3b634..158427e8124e 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -100,7 +100,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;

--
2.25.1


2022-12-29 02:47:54

by Sungjong Seo

[permalink] [raw]
Subject: RE: [PATCH v1] exfat: fix reporting fs error when reading dir beyond EOF

> 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()")
>
> Signed-off-by: Yuezhang Mo <[email protected]>
> Reviewed-by: Andy Wu <[email protected]>
> Reviewed-by: Aoyama Wataru <[email protected]>

Looks good. Thanks.

Reviewed-by: Sungjong Seo <[email protected]>

> ---
> fs/exfat/dir.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
> index 1122bee3b634..158427e8124e 100644
> --- a/fs/exfat/dir.c
> +++ b/fs/exfat/dir.c
> @@ -100,7 +100,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;
>
> --
> 2.25.1


2022-12-30 01:38:09

by Namjae Jeon

[permalink] [raw]
Subject: Re: [PATCH v1] exfat: fix reporting fs error when reading dir beyond EOF

2022-12-26 16:23 GMT+09:00, [email protected] <[email protected]>:
> 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()")
>
> Signed-off-by: Yuezhang Mo <[email protected]>
> Reviewed-by: Andy Wu <[email protected]>
> Reviewed-by: Aoyama Wataru <[email protected]>
Applied, Thanks for your patch!