From cc9d09fef78410bcd37ac05168cbd5f6dd75d3d2 Mon Sep 17 00:00:00 2001 From: Hyunchul Lee Date: Wed, 19 Aug 2026 16:19:00 +0900 Subject: [PATCH] ntfs: reject invalid MFT LCNs from boot sector The NTFS boot sector stores the MFT and MFTMirr locations as unsigned 64-bit LCNs, but parse_ntfs_boot_sector() decoded them into an s64. A crafted high-bit value could therefore become negative and pass the existing upper-bound check. The invalid value then propagated into the MFT zone allocator and could result in an out-of-bounds access to lcn_empty_bits_per_page. Fixes: 11ccc9107dc4 ("ntfs: update runlist handling and cluster allocator") Reported-by: Robert Morris Closes: https://lore.kernel.org/all/57514.1787000602@localhost Cc: stable@vger.kernel.org Signed-off-by: Hyunchul Lee Signed-off-by: Namjae Jeon --- fs/ntfs/super.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 8abe7bee4c0d..cd8fa2c13370 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -645,7 +645,7 @@ static bool parse_ntfs_boot_sector(struct ntfs_volume *vol, { unsigned int sectors_per_cluster, sectors_per_cluster_bits, nr_hidden_sects; int clusters_per_mft_record, clusters_per_index_record; - s64 ll; + u64 ll; vol->sector_size = le16_to_cpu(b->bpb.bytes_per_sector); vol->sector_size_bits = ffs(vol->sector_size) - 1; @@ -755,23 +755,23 @@ static bool parse_ntfs_boot_sector(struct ntfs_volume *vol, * the same as it is much faster on 32-bit CPUs. */ ll = le64_to_cpu(b->number_of_sectors) >> sectors_per_cluster_bits; - if ((u64)ll >= 1ULL << 32) { + if (ll >= 1ULL << 32) { ntfs_error(vol->sb, "Cannot handle 64-bit clusters."); return false; } vol->nr_clusters = ll; ntfs_debug("vol->nr_clusters = 0x%llx", vol->nr_clusters); ll = le64_to_cpu(b->mft_lcn); - if (ll >= vol->nr_clusters) { - ntfs_error(vol->sb, "MFT LCN (%lli, 0x%llx) is beyond end of volume. Weird.", + if (ll >= (u64)vol->nr_clusters) { + ntfs_error(vol->sb, "MFT LCN (%llu, 0x%llx) is beyond end of volume. Weird.", ll, ll); return false; } vol->mft_lcn = ll; ntfs_debug("vol->mft_lcn = 0x%llx", vol->mft_lcn); ll = le64_to_cpu(b->mftmirr_lcn); - if (ll >= vol->nr_clusters) { - ntfs_error(vol->sb, "MFTMirr LCN (%lli, 0x%llx) is beyond end of volume. Weird.", + if (ll >= (u64)vol->nr_clusters) { + ntfs_error(vol->sb, "MFTMirr LCN (%llu, 0x%llx) is beyond end of volume. Weird.", ll, ll); return false; }