* [PATCH AUTOSEL 6.12 13/93] exfat: fix double free in delayed_free
[not found] <20250601233402.3512823-1-sashal@kernel.org>
@ 2025-06-01 23:32 ` Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 18/93] exfat: do not clear volume dirty flag during sync Sasha Levin
1 sibling, 0 replies; 2+ messages in thread
From: Sasha Levin @ 2025-06-01 23:32 UTC (permalink / raw)
To: patches, stable
Cc: Namjae Jeon, Jianzhou Zhao, Sasha Levin, sj1557.seo,
linux-fsdevel, linux-kernel
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 1f3d9724e16d62c7d42c67d6613b8512f2887c22 ]
The double free could happen in the following path.
exfat_create_upcase_table()
exfat_create_upcase_table() : return error
exfat_free_upcase_table() : free ->vol_utbl
exfat_load_default_upcase_table : return error
exfat_kill_sb()
delayed_free()
exfat_free_upcase_table() <--------- double free
This patch set ->vol_util as NULL after freeing it.
Reported-by: Jianzhou Zhao <xnxc22xnxc22@qq.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Based on my thorough analysis of the commit and examination of the
kernel tree, here is my assessment: **YES** This commit should be
backported to stable kernel trees. Here's my extensive analysis: ## Code
Analysis **The Problem:** The commit fixes a classic double-free
vulnerability in the exfat filesystem. Looking at the current kernel
code, the vulnerability exists in this execution path: 1.
`exfat_create_upcase_table()` calls `exfat_load_upcase_table()` which
may fail 2. On failure (`ret && ret != -EIO`), it calls
`exfat_free_upcase_table(sbi)` 3. Then it goes to `load_default:` and
calls `exfat_load_default_upcase_table()` which may also fail 4. When
the filesystem unmounts, `exfat_kill_sb()` → `delayed_free()` →
`exfat_free_upcase_table(sbi)` is called again **The Current Vulnerable
Code:** ```c void exfat_free_upcase_table(struct exfat_sb_info *sbi) {
kvfree(sbi->vol_utbl); // No NULL assignment - vulnerable to double free
} ``` **The Fix:** The patch adds `sbi->vol_utbl = NULL;` after the
`kvfree()`, which prevents the double-free because `kvfree(NULL)` is
safe. ## Backport Criteria Assessment **1. Bug Severity: HIGH** - This
is a memory corruption vulnerability (double-free) - Double-free bugs
can lead to heap corruption, crashes, and potentially security exploits
- The bug affects the reliability and security of the exfat filesystem
**2. Fix Quality: EXCELLENT** - The fix is minimal (just one line:
`sbi->vol_utbl = NULL;`) - Extremely low risk of introducing regressions
- Follows standard defensive programming practices - The fix is
contained within a single function **3. Backport Suitability: PERFECT**
- Small, isolated change that doesn't affect any APIs - No architectural
changes or new features - The fix addresses the root cause directly -
Compatible with all kernel versions that have the vulnerable code **4.
Historical Context:** Looking at the similar commits provided: -
**Similar Commit #2** (Status: YES): Also a memory leak fix in exfat
with `Cc: stable@vger.kernel.org` - **Similar Commit #4** (Status: YES):
Another memory corruption prevention fix in exfat - Both demonstrate
that small, targeted memory management fixes in exfat are appropriate
for stable backporting **5. Impact Assessment:** - **User Impact:** High
- prevents filesystem crashes and potential data corruption - **Risk:**
Very low - the change only affects error paths and adds defensive
programming - **Complexity:** Minimal - single line change with clear
semantics **6. RCU Context:** The commit a13d1a4de3b0 introduced the
`delayed_free()` mechanism that made this double-free possible, making
this fix essential for kernels with that change. ## Conclusion This
commit represents exactly the type of fix that stable kernels need: a
small, surgical fix for a potentially serious memory corruption bug with
minimal risk of regression. The double-free vulnerability could lead to
system instability and the fix is trivial to apply and verify. Given the
similarities with other exfat memory management fixes that were
successfully backported, this should definitely be included in stable
kernel trees.
fs/exfat/nls.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/exfat/nls.c b/fs/exfat/nls.c
index d47896a895965..1729bf42eb516 100644
--- a/fs/exfat/nls.c
+++ b/fs/exfat/nls.c
@@ -801,4 +801,5 @@ int exfat_create_upcase_table(struct super_block *sb)
void exfat_free_upcase_table(struct exfat_sb_info *sbi)
{
kvfree(sbi->vol_utbl);
+ sbi->vol_utbl = NULL;
}
--
2.39.5
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH AUTOSEL 6.12 18/93] exfat: do not clear volume dirty flag during sync
[not found] <20250601233402.3512823-1-sashal@kernel.org>
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 13/93] exfat: fix double free in delayed_free Sasha Levin
@ 2025-06-01 23:32 ` Sasha Levin
1 sibling, 0 replies; 2+ messages in thread
From: Sasha Levin @ 2025-06-01 23:32 UTC (permalink / raw)
To: patches, stable
Cc: Yuezhang Mo, Sungjong Seo, Namjae Jeon, Sasha Levin,
linux-fsdevel, linux-kernel
From: Yuezhang Mo <Yuezhang.Mo@sony.com>
[ Upstream commit 46a557694b464881b3c2c4a0ba389a6436419a37 ]
xfstests generic/482 tests the file system consistency after each
FUA operation. It fails when run on exfat.
exFAT clears the volume dirty flag with a FUA operation during sync.
Since s_lock is not held when data is being written to a file, sync
can be executed at the same time. When data is being written to a
file, the FAT chain is updated first, and then the file size is
updated. If sync is executed between updating them, the length of the
FAT chain may be inconsistent with the file size.
To avoid the situation where the file system is inconsistent but the
volume dirty flag is cleared, this commit moves the clearing of the
volume dirty flag from exfat_fs_sync() to exfat_put_super(), so that
the volume dirty flag is not cleared until unmounting. After the
move, there is no additional action during sync, so exfat_fs_sync()
can be deleted.
Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Looking at this commit to analyze for backport suitability: **YES** This
commit addresses a critical data consistency issue in the exFAT
filesystem that can cause file corruption when remounting read-only. The
commit resolves a race condition where the volume dirty flag could be
cleared prematurely, potentially leaving the filesystem in an
inconsistent state. ## Key Analysis Points: **1. Critical Bug Fix**: The
commit message clearly identifies this fixes a specific test failure
(xfstests generic/482) that tests filesystem consistency. File system
corruption is a serious user-facing issue that affects data integrity.
**2. Small, Contained Changes**: The code changes are minimal and
surgical: - Removes the `exfat_sync_fs()` function (only 20 lines) -
Moves `exfat_clear_volume_dirty(sb)` call from sync to unmount
(`exfat_put_super()`) - Updates the remount function to explicitly sync
and clear dirty flag - Removes the `.sync_fs` callback from the
super_operations structure **3. Race Condition Fix**: The commit
addresses a fundamental race condition where: - FAT chain updates happen
first - File size updates happen second - If sync occurs between these
steps, the filesystem becomes inconsistent - The volume dirty flag could
be cleared despite the inconsistency **4. Follows Stable Tree Rules**:
This is exactly the type of fix that should be backported: - Fixes file
system corruption - Minimal risk of regression - Small, focused change -
Addresses data integrity issue **5. Similar Historical Precedents**:
Looking at the similar commits provided: - Similar Commit #2 (Status:
YES) also deals with exFAT fsync functionality and data consistency -
Similar Commit #4 (Status: YES) addresses exFAT remount synchronization
issues - These precedents show that exFAT data consistency fixes are
typically backported **6. No Architectural Changes**: The fix doesn't
introduce new features or make architectural changes - it simply moves
when the volume dirty flag is cleared to prevent premature clearing
during race conditions. **7. Critical Subsystem**: Filesystem data
integrity is a critical subsystem where corruption bugs must be fixed to
protect user data. The code changes are straightforward - instead of
clearing the dirty flag during sync operations (which can race with
ongoing writes), the flag is only cleared at unmount time when no more
writes can occur. This ensures the filesystem dirty state accurately
reflects whether pending changes exist.
fs/exfat/super.c | 30 +++++++-----------------------
1 file changed, 7 insertions(+), 23 deletions(-)
diff --git a/fs/exfat/super.c b/fs/exfat/super.c
index bd57844414aa6..04fdc8ae2ecc4 100644
--- a/fs/exfat/super.c
+++ b/fs/exfat/super.c
@@ -36,31 +36,12 @@ static void exfat_put_super(struct super_block *sb)
struct exfat_sb_info *sbi = EXFAT_SB(sb);
mutex_lock(&sbi->s_lock);
+ exfat_clear_volume_dirty(sb);
exfat_free_bitmap(sbi);
brelse(sbi->boot_bh);
mutex_unlock(&sbi->s_lock);
}
-static int exfat_sync_fs(struct super_block *sb, int wait)
-{
- struct exfat_sb_info *sbi = EXFAT_SB(sb);
- int err = 0;
-
- if (unlikely(exfat_forced_shutdown(sb)))
- return 0;
-
- if (!wait)
- return 0;
-
- /* If there are some dirty buffers in the bdev inode */
- mutex_lock(&sbi->s_lock);
- sync_blockdev(sb->s_bdev);
- if (exfat_clear_volume_dirty(sb))
- err = -EIO;
- mutex_unlock(&sbi->s_lock);
- return err;
-}
-
static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf)
{
struct super_block *sb = dentry->d_sb;
@@ -228,7 +209,6 @@ static const struct super_operations exfat_sops = {
.write_inode = exfat_write_inode,
.evict_inode = exfat_evict_inode,
.put_super = exfat_put_super,
- .sync_fs = exfat_sync_fs,
.statfs = exfat_statfs,
.show_options = exfat_show_options,
.shutdown = exfat_shutdown,
@@ -761,10 +741,14 @@ static void exfat_free(struct fs_context *fc)
static int exfat_reconfigure(struct fs_context *fc)
{
+ struct super_block *sb = fc->root->d_sb;
fc->sb_flags |= SB_NODIRATIME;
- /* volume flag will be updated in exfat_sync_fs */
- sync_filesystem(fc->root->d_sb);
+ sync_filesystem(sb);
+ mutex_lock(&EXFAT_SB(sb)->s_lock);
+ exfat_clear_volume_dirty(sb);
+ mutex_unlock(&EXFAT_SB(sb)->s_lock);
+
return 0;
}
--
2.39.5
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-06-01 23:34 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20250601233402.3512823-1-sashal@kernel.org>
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 13/93] exfat: fix double free in delayed_free Sasha Levin
2025-06-01 23:32 ` [PATCH AUTOSEL 6.12 18/93] exfat: do not clear volume dirty flag during sync Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).