<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/git/stable/linux.git/fs/exfat/dir.c, branch linux-7.2.y</title>
<subtitle>Linux kernel stable tree</subtitle>
<id>https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/atom?h=linux-7.2.y</id>
<link rel='self' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/atom?h=linux-7.2.y'/>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/'/>
<updated>2026-06-15T11:01:04+00:00</updated>
<entry>
<title>exfat: bound uniname advance in exfat_find_dir_entry()</title>
<updated>2026-06-15T11:01:04+00:00</updated>
<author>
<name>Bryam Vargas</name>
<email>hexlabsecurity@proton.me</email>
</author>
<published>2026-06-12T19:29:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=3a1230e7b043c62737b05a3e9275ca83a43ad20a'/>
<id>urn:sha1:3a1230e7b043c62737b05a3e9275ca83a43ad20a</id>
<content type='text'>
In exfat_find_dir_entry(), each TYPE_EXTEND (file name) entry advances the
output pointer by a fixed amount while the loop guard only tracks the
accumulated name length:

	if (++order == 2)
		uniname = p_uniname-&gt;name;
	else
		uniname += EXFAT_FILE_NAME_LEN;
	len = exfat_extract_uni_name(ep, entry_uniname);
	name_len += len;
	unichar = *(uniname+len);
	*(uniname+len) = 0x0;

uniname grows by EXFAT_FILE_NAME_LEN (15) per name entry, but name_len
grows only by the actual extracted length, which is shorter when a name
fragment contains an early NUL.  The only guard is
`name_len &gt;= MAX_NAME_LENGTH`, so a crafted directory with many short
name fragments lets uniname run far past the
p_uniname-&gt;name[MAX_NAME_LENGTH + 3] buffer while name_len stays small,
causing an out-of-bounds read and write at *(uniname+len).

The sibling extractor exfat_get_uniname_from_ext_entry() already stops
on a short fragment (the lockstep `len != EXFAT_FILE_NAME_LEN` guard
added in commit d42334578eba ("exfat: check if filename entries exceeds
max filename length")); exfat_find_dir_entry() never got the
equivalent.  Track the per-entry write offset as a count and reject a
fragment once the offset, or the offset plus the extracted length, would
exceed MAX_NAME_LENGTH, before forming the output pointer.

Fixes: ca06197382bd ("exfat: add directory operations")
Cc: stable@vger.kernel.org
Suggested-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
Signed-off-by: Bryam Vargas &lt;hexlabsecurity@proton.me&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
</entry>
<entry>
<title>exfat: preserve benign secondary entries during rename and move</title>
<updated>2026-06-15T11:00:53+00:00</updated>
<author>
<name>Rochan Avlur</name>
<email>rochan.avlur@gmail.com</email>
</author>
<published>2026-05-28T14:21:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=942296784b2a9439651750c42f540bf2579b330f'/>
<id>urn:sha1:942296784b2a9439651750c42f540bf2579b330f</id>
<content type='text'>
Commit 8258ef28001a ("exfat: handle unreconized benign secondary
entries") added cluster freeing for benign secondary entries inside
exfat_remove_entries().  However, exfat_remove_entries() is also called
from the rename and move paths (exfat_rename_file and exfat_move_file),
where the old entry set is being relocated rather than deleted.  This
causes benign secondary entries such as vendor extension entries to be
silently destroyed on rename or cross-directory move, violating the
exFAT spec requirement (section 8.2) that implementations preserve
unrecognized benign secondary entries.

Fix this by adding a free_benign parameter to exfat_remove_entries()
so callers can suppress cluster freeing during relocation, and
extending exfat_init_ext_entry() to copy trailing benign secondary
entries from the old entry set into the new one internally.  Also
clean up the error paths to delete newly allocated entries on failure.

Fixes: 8258ef28001a ("exfat: handle unreconized benign secondary entries")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/linux-fsdevel/CAG7tbBV--waov7XVu2FHQEc6paR92dufS=em9DW5Kzsrpu3iQg@mail.gmail.com/
Signed-off-by: Rochan Avlur &lt;rochan.avlur@gmail.com&gt;
Reviewed-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
</entry>
<entry>
<title>exfat: add support for multi-cluster allocation</title>
<updated>2026-06-15T10:55:42+00:00</updated>
<author>
<name>Namjae Jeon</name>
<email>linkinjeon@kernel.org</email>
</author>
<published>2026-05-07T00:05:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=286ae368871d2a93b68148c7684b8cff63c9ba80'/>
<id>urn:sha1:286ae368871d2a93b68148c7684b8cff63c9ba80</id>
<content type='text'>
Currently exfat_map_cluster() allocates and returns only one cluster
at a time even when more clusters are needed. This causes multiple
FAT walks and repeated allocation calls during large sequential writes
or when using iomap for writes. This change exfat_map_cluster() and
exfat_alloc_cluster() to be able to allocate multiple contiguous
clusters.

Acked-by: Christoph Hellwig &lt;hch@lst.de&gt;
Acked-by: "Darrick J. Wong" &lt;djwong@kernel.org&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
</entry>
<entry>
<title>exfat: replace unsafe macros with static inline functions</title>
<updated>2026-06-15T10:55:29+00:00</updated>
<author>
<name>Namjae Jeon</name>
<email>linkinjeon@kernel.org</email>
</author>
<published>2026-04-21T07:42:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=f07db38084dc45162d5fe2871ed72674ddc0f9ae'/>
<id>urn:sha1:f07db38084dc45162d5fe2871ed72674ddc0f9ae</id>
<content type='text'>
The current exFAT driver relies on various macros for unit conversions
between clusters, blocks, sectors, and directory entries. These macros
are structurally unsafe as they lack type enforcement and are prone to
potential integer overflows during bit-shift operations, especially
on 64-bit architectures. Replace all arithmetic macros with static inline
functions to provide strict type checking and explicit casting.

Acked-by: Christoph Hellwig &lt;hch@lst.de&gt;
Acked-by: "Darrick J. Wong" &lt;djwong@kernel.org&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
</entry>
<entry>
<title>exfat: fix potential use-after-free in exfat_find_dir_entry()</title>
<updated>2026-06-15T10:55:21+00:00</updated>
<author>
<name>Michael Bommarito</name>
<email>michael.bommarito@gmail.com</email>
</author>
<published>2026-04-22T15:58:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=3f5f8ee9917cc2b9076ac533492d8a200edcabb8'/>
<id>urn:sha1:3f5f8ee9917cc2b9076ac533492d8a200edcabb8</id>
<content type='text'>
In exfat_find_dir_entry(), the buffer_head obtained from
exfat_get_dentry() is released with brelse(bh) before the fall-through
TYPE_EXTEND branch reads the directory entry through ep (which points
into bh-&gt;b_data):

	brelse(bh);
	if (entry_type == TYPE_EXTEND) {
		...
		len = exfat_extract_uni_name(ep, entry_uniname);
		...
	}

After brelse() drops our reference, nothing guarantees that the
underlying page backing bh-&gt;b_data remains valid for the subsequent
exfat_extract_uni_name() read. This is the same pattern fixed in
commit fc961522ddbd ("exfat: Fix potential use after free in
exfat_load_upcase_table()").

Move brelse(bh) so it runs after ep is no longer dereferenced on
each branch.

Confirmed on QEMU x86_64 with CONFIG_KASAN=y + CONFIG_DEBUG_PAGEALLOC=y
+ CONFIG_PAGE_POISONING=y on linux-next, using a crafted exFAT image
(long filename with same-hash collisions forcing the TYPE_EXTEND path).
With a debug-only invalidate_bdev() inserted between brelse(bh) and
the ep read to make the stale-deref window deterministic, the
unpatched kernel faults:

  BUG: KASAN: use-after-free in exfat_find_dir_entry+0x133b/0x15a0
  BUG: unable to handle page fault for address: ffff88801a5fa0c2
  Oops: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN NOPTI
  RIP: 0010:exfat_find_dir_entry+0x1188/0x15a0

With this patch applied, the same instrumented harness completes
cleanly under the same sanitizer stack. I have not reproduced a
crash on an uninstrumented kernel under ordinary reclaim; the
instrumented A/B establishes the lifetime violation and that the
patch closes it, not an unaided triggerability claim.

Fixes: ca06197382bd ("exfat: add directory operations")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Michael Bommarito &lt;michael.bommarito@gmail.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
</entry>
<entry>
<title>exfat: use exfat_chain_advance helper</title>
<updated>2026-04-03T13:41:10+00:00</updated>
<author>
<name>Chi Zhiling</name>
<email>chizhiling@kylinos.cn</email>
</author>
<published>2026-04-03T08:05:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=08cf4a8181b4378a0a50ea370391f30032c4e4ec'/>
<id>urn:sha1:08cf4a8181b4378a0a50ea370391f30032c4e4ec</id>
<content type='text'>
Replace open-coded cluster chain walking logic with exfat_chain_advance()
across exfat_readdir, exfat_find_dir_entry, exfat_count_dir_entries,
exfat_search_empty_slot and exfat_check_dir_empty.

Signed-off-by: Chi Zhiling &lt;chizhiling@kylinos.cn&gt;
Reviewed-by: Sungjong Seo &lt;sj1557.seo@samsung.com&gt;
Reviewed-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
</entry>
<entry>
<title>exfat: use exfat_cluster_walk helper</title>
<updated>2026-04-03T13:41:05+00:00</updated>
<author>
<name>Chi Zhiling</name>
<email>chizhiling@kylinos.cn</email>
</author>
<published>2026-04-03T08:05:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=6f2cbe45c675d21e104856fc5917048e772a0dcf'/>
<id>urn:sha1:6f2cbe45c675d21e104856fc5917048e772a0dcf</id>
<content type='text'>
Replace the custom exfat_walk_fat_chain() function and open-coded
FAT chain walking logic with the exfat_cluster_walk() helper across
exfat_find_location, __exfat_get_dentry_set, and exfat_map_cluster.

Suggested-by: Sungjong Seo &lt;sj1557.seo@samsung.com&gt;
Signed-off-by: Chi Zhiling &lt;chizhiling@kylinos.cn&gt;
Reviewed-by: Sungjong Seo &lt;sj1557.seo@samsung.com&gt;
Reviewed-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
</entry>
<entry>
<title>exfat: fix incorrect directory checksum after rename to shorter name</title>
<updated>2026-04-03T13:41:02+00:00</updated>
<author>
<name>Chi Zhiling</name>
<email>chizhiling@kylinos.cn</email>
</author>
<published>2026-04-03T08:05:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=ff37797badd831797b8a27830fe5046d7e23fdc3'/>
<id>urn:sha1:ff37797badd831797b8a27830fe5046d7e23fdc3</id>
<content type='text'>
When renaming a file in-place to a shorter name, exfat_remove_entries
marks excess entries as DELETED, but es-&gt;num_entries is not updated
accordingly. As a result, exfat_update_dir_chksum iterates over the
deleted entries and computes an incorrect checksum.

This does not lead to persistent corruption because mark_inode_dirty()
is called afterward, and __exfat_write_inode later recomputes the
checksum using the correct num_entries value.

Fix by setting es-&gt;num_entries = num_entries in exfat_init_ext_entry.

Signed-off-by: Chi Zhiling &lt;chizhiling@kylinos.cn&gt;
Reviewed-by: Sungjong Seo &lt;sj1557.seo@samsung.com&gt;
Reviewed-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
</entry>
<entry>
<title>exfat: use readahead helper in exfat_get_dentry</title>
<updated>2026-03-05T12:09:28+00:00</updated>
<author>
<name>Chi Zhiling</name>
<email>chizhiling@kylinos.cn</email>
</author>
<published>2026-03-03T03:14:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=7094b09ea713d537f801a48853681c1b4205df2e'/>
<id>urn:sha1:7094b09ea713d537f801a48853681c1b4205df2e</id>
<content type='text'>
Replace the custom exfat_dir_readahead() function with the unified
exfat_blk_readahead() helper in exfat_get_dentry(). This removes
the duplicate readahead implementation and uses the common interface,
also reducing code complexity.

Signed-off-by: Chi Zhiling &lt;chizhiling@kylinos.cn&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
</entry>
<entry>
<title>exfat: Fix bitwise operation having different size</title>
<updated>2026-03-04T10:23:59+00:00</updated>
<author>
<name>Philipp Hahn</name>
<email>phahn-oss@avm.de</email>
</author>
<published>2026-03-03T10:59:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=3dce5bb82c97fc2ac28d80d496120a6525ce3fb7'/>
<id>urn:sha1:3dce5bb82c97fc2ac28d80d496120a6525ce3fb7</id>
<content type='text'>
cpos has type loff_t (long long), while s_blocksize has type u32. The
inversion wil happen on u32, the coercion to s64 happens afterwards and
will do 0-left-paddding, resulting in the upper bits getting masked out.

Cast s_blocksize to loff_t before negating it.

Found by static code analysis using Klocwork.

Signed-off-by: Philipp Hahn &lt;phahn-oss@avm.de&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
</entry>
</feed>
