diff options
| author | Jaehun Gou <p22gone@gmail.com> | 2025-10-14 22:01:46 +0900 |
|---|---|---|
| committer | Namjae Jeon <linkinjeon@kernel.org> | 2025-10-15 14:37:21 +0900 |
| commit | 82ebecdc74ff555daf70b811d854b1f32a296bea (patch) | |
| tree | 977beda498b5701baad37548abffef3edecfb900 /fs | |
| parent | Merge tag 'nfsd-6.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/... (diff) | |
| download | linux-82ebecdc74ff555daf70b811d854b1f32a296bea.tar.gz linux-82ebecdc74ff555daf70b811d854b1f32a296bea.zip | |
exfat: fix improper check of dentry.stream.valid_size
We found an infinite loop bug in the exFAT file system that can lead to a
Denial-of-Service (DoS) condition. When a dentry in an exFAT filesystem is
malformed, the following system calls — SYS_openat, SYS_ftruncate, and
SYS_pwrite64 — can cause the kernel to hang.
Root cause analysis shows that the size validation code in exfat_find()
does not check whether dentry.stream.valid_size is negative. As a result,
the system calls mentioned above can succeed and eventually trigger the DoS
issue.
This patch adds a check for negative dentry.stream.valid_size to prevent
this vulnerability.
Co-developed-by: Seunghun Han <kkamagui@gmail.com>
Signed-off-by: Seunghun Han <kkamagui@gmail.com>
Co-developed-by: Jihoon Kwon <jimmyxyz010315@gmail.com>
Signed-off-by: Jihoon Kwon <jimmyxyz010315@gmail.com>
Signed-off-by: Jaehun Gou <p22gone@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/exfat/namei.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index 7eb9c67fd35f..2364b49f050a 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -642,10 +642,14 @@ static int exfat_find(struct inode *dir, const struct qstr *qname, info->type = exfat_get_entry_type(ep); info->attr = le16_to_cpu(ep->dentry.file.attr); - info->size = le64_to_cpu(ep2->dentry.stream.valid_size); info->valid_size = le64_to_cpu(ep2->dentry.stream.valid_size); info->size = le64_to_cpu(ep2->dentry.stream.size); + if (info->valid_size < 0) { + exfat_fs_error(sb, "data valid size is invalid(%lld)", info->valid_size); + return -EIO; + } + if (unlikely(EXFAT_B_TO_CLU_ROUND_UP(info->size, sbi) > sbi->used_clusters)) { exfat_fs_error(sb, "data size is invalid(%lld)", info->size); return -EIO; |
