Skip to content

Commit 5428dc1

Browse files
committed
Merge tag 'exfat-for-6.13-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat
Pull exfat fixes from Namjae Jeon: "All fixes are for issues reported by syzbot: - Fix wrong error return in exfat_find_empty_entry() - Fix a endless loop by self-linked chain - fix a KMSAN uninit-value issue in exfat_extend_valid_size()" * tag 'exfat-for-6.13-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat: exfat: fix the infinite loop in __exfat_free_cluster() exfat: fix the new buffer was not zeroed before writing exfat: fix the infinite loop in exfat_readdir() exfat: fix exfat_find_empty_entry() not returning error on failure
2 parents cd6313b + a5324b3 commit 5428dc1

File tree

4 files changed

+20
-3
lines changed

4 files changed

+20
-3
lines changed

fs/exfat/dir.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
122122
type = exfat_get_entry_type(ep);
123123
if (type == TYPE_UNUSED) {
124124
brelse(bh);
125-
break;
125+
goto out;
126126
}
127127

128128
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
170170
}
171171
}
172172

173+
out:
173174
dir_entry->namebuf.lfn[0] = '\0';
174175
*cpos = EXFAT_DEN_TO_B(dentry);
175176
return 0;

fs/exfat/fatent.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,16 @@ static int __exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain
216216

217217
if (err)
218218
goto dec_used_clus;
219+
220+
if (num_clusters >= sbi->num_clusters - EXFAT_FIRST_CLUSTER) {
221+
/*
222+
* The cluster chain includes a loop, scan the
223+
* bitmap to get the number of used clusters.
224+
*/
225+
exfat_count_used_clusters(sb, &sbi->used_clusters);
226+
227+
return 0;
228+
}
219229
} while (clu != EXFAT_EOF_CLUSTER);
220230
}
221231

fs/exfat/file.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ static int exfat_extend_valid_size(struct file *file, loff_t new_valid_size)
545545
while (pos < new_valid_size) {
546546
u32 len;
547547
struct folio *folio;
548+
unsigned long off;
548549

549550
len = PAGE_SIZE - (pos & (PAGE_SIZE - 1));
550551
if (pos + len > new_valid_size)
@@ -554,6 +555,9 @@ static int exfat_extend_valid_size(struct file *file, loff_t new_valid_size)
554555
if (err)
555556
goto out;
556557

558+
off = offset_in_folio(folio, pos);
559+
folio_zero_new_buffers(folio, off, off + len);
560+
557561
err = ops->write_end(file, mapping, pos, len, len, folio, NULL);
558562
if (err < 0)
559563
goto out;
@@ -563,6 +567,8 @@ static int exfat_extend_valid_size(struct file *file, loff_t new_valid_size)
563567
cond_resched();
564568
}
565569

570+
return 0;
571+
566572
out:
567573
return err;
568574
}

fs/exfat/namei.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,8 @@ static int exfat_find_empty_entry(struct inode *inode,
330330

331331
while ((dentry = exfat_search_empty_slot(sb, &hint_femp, p_dir,
332332
num_entries, es)) < 0) {
333-
if (dentry == -EIO)
334-
break;
333+
if (dentry != -ENOSPC)
334+
return dentry;
335335

336336
if (exfat_check_max_dentries(inode))
337337
return -ENOSPC;

0 commit comments

Comments
 (0)