Commit 5428dc19 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents cd6313be a5324b3a
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -122,7 +122,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
			type = exfat_get_entry_type(ep);
			if (type == TYPE_UNUSED) {
				brelse(bh);
				break;
				goto out;
			}

			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
		}
	}

out:
	dir_entry->namebuf.lfn[0] = '\0';
	*cpos = EXFAT_DEN_TO_B(dentry);
	return 0;
+10 −0
Original line number Diff line number Diff line
@@ -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);
	}

+6 −0
Original line number Diff line number Diff line
@@ -545,6 +545,7 @@ static int exfat_extend_valid_size(struct file *file, loff_t new_valid_size)
	while (pos < new_valid_size) {
		u32 len;
		struct folio *folio;
		unsigned long off;

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

		off = offset_in_folio(folio, pos);
		folio_zero_new_buffers(folio, off, off + len);

		err = ops->write_end(file, mapping, pos, len, len, folio, NULL);
		if (err < 0)
			goto out;
@@ -563,6 +567,8 @@ static int exfat_extend_valid_size(struct file *file, loff_t new_valid_size)
		cond_resched();
	}

	return 0;

out:
	return err;
}
+2 −2
Original line number Diff line number Diff line
@@ -330,8 +330,8 @@ static int exfat_find_empty_entry(struct inode *inode,

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

		if (exfat_check_max_dentries(inode))
			return -ENOSPC;