[lvc-project] [PATCH 6.1] Revert "fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super"

Fedor Pchelkin pchelkin at ispras.ru
Sat Apr 5 20:32:13 MSK 2025


This reverts commit f9c572d02fcced59c68f0287680fef9a5e0f5c9a which is
commit 91a4b1ee78cb100b19b70f077c247f211110348f upstream.

The backported version of the fix does a lot of things which it shouldn't
do and which the upstream commit doesn't touch as well.

Various auto-formatting changes and duplicate assignments made by the
ported version are not a big deal on its own, but what is more important,
it just drops 'sbi->zone_max' initialization for an unknown reason.
Original commit doesn't ever intend to do anything with that.

Better revert this commit from the stable branch for now.

Found by Linux Verification Center (linuxtesting.org).

Signed-off-by: Fedor Pchelkin <pchelkin at ispras.ru>
---

FWIW there exists another variant of this backport patch [1] which at a
quick glance looks more appropriate and was posted nearly a year ago.

I've added Roman - author of [1] - to Cc. Maybe he would be interested in
resending this so that it'd appear in your queue again. Anyway, it's up to
you to decide whether to take Roman's patch or just ignore it...

[1]: https://lore.kernel.org/stable/20240424101114.192681-2-r.smirnov@omp.ru/

 fs/ntfs3/ntfs_fs.h |  2 --
 fs/ntfs3/super.c   | 68 +++++++++++++++-------------------------------
 2 files changed, 22 insertions(+), 48 deletions(-)

diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
index f2f32e304b3d..05d9abd66b37 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -42,11 +42,9 @@ enum utf16_endian;
 #define MINUS_ONE_T			((size_t)(-1))
 /* Biggest MFT / smallest cluster */
 #define MAXIMUM_BYTES_PER_MFT		4096
-#define MAXIMUM_SHIFT_BYTES_PER_MFT	12
 #define NTFS_BLOCKS_PER_MFT_RECORD	(MAXIMUM_BYTES_PER_MFT / 512)
 
 #define MAXIMUM_BYTES_PER_INDEX		4096
-#define MAXIMUM_SHIFT_BYTES_PER_INDEX	12
 #define NTFS_BLOCKS_PER_INODE		(MAXIMUM_BYTES_PER_INDEX / 512)
 
 /* NTFS specific error code when fixup failed. */
diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
index 674a16c0c66b..eee54214f4a3 100644
--- a/fs/ntfs3/super.c
+++ b/fs/ntfs3/super.c
@@ -680,7 +680,7 @@ static u32 true_sectors_per_clst(const struct NTFS_BOOT *boot)
  * ntfs_init_from_boot - Init internal info from on-disk boot sector.
  */
 static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
-		  u64 dev_size)
+			       u64 dev_size)
 {
 	struct ntfs_sb_info *sbi = sb->s_fs_info;
 	int err;
@@ -705,12 +705,12 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
 
 	/* 0x55AA is not mandaroty. Thanks Maxim Suhanov*/
 	/*if (0x55 != boot->boot_magic[0] || 0xAA != boot->boot_magic[1])
-	 *  goto out;
+	 *	goto out;
 	 */
 
 	boot_sector_size = (u32)boot->bytes_per_sector[1] << 8;
 	if (boot->bytes_per_sector[0] || boot_sector_size < SECTOR_SIZE ||
-		!is_power_of_2(boot_sector_size)) {
+	    !is_power_of_2(boot_sector_size)) {
 		goto out;
 	}
 
@@ -733,49 +733,15 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
 
 	/* Check MFT record size. */
 	if ((boot->record_size < 0 &&
-		 SECTOR_SIZE > (2U << (-boot->record_size))) ||
-		(boot->record_size >= 0 && !is_power_of_2(boot->record_size))) {
-		goto out;
-	}
-
-	/* Calculate cluster size */
-	sbi->cluster_size = boot_sector_size * sct_per_clst;
-	sbi->cluster_bits = blksize_bits(sbi->cluster_size);
-
-	if (boot->record_size >= 0) {
-		record_size = (u32)boot->record_size << sbi->cluster_bits;
-	} else if (-boot->record_size <= MAXIMUM_SHIFT_BYTES_PER_MFT) {
-		record_size = 1u << (-boot->record_size);
-	} else {
-		ntfs_err(sb, "%s: invalid record size %d.", "NTFS",
-			 boot->record_size);
-		goto out;
-	}
-
-	sbi->record_size = record_size;
-	sbi->record_bits = blksize_bits(record_size);
-	sbi->attr_size_tr = (5 * record_size >> 4); // ~320 bytes
-
-	if (record_size > MAXIMUM_BYTES_PER_MFT) {
-		ntfs_err(sb, "Unsupported bytes per MFT record %u.",
-			 record_size);
-		goto out;
-	}
-
-	if (boot->index_size >= 0) {
-		sbi->index_size = (u32)boot->index_size << sbi->cluster_bits;
-	} else if (-boot->index_size <= MAXIMUM_SHIFT_BYTES_PER_INDEX) {
-		sbi->index_size = 1u << (-boot->index_size);
-	} else {
-		ntfs_err(sb, "%s: invalid index size %d.", "NTFS",
-			 boot->index_size);
+	     SECTOR_SIZE > (2U << (-boot->record_size))) ||
+	    (boot->record_size >= 0 && !is_power_of_2(boot->record_size))) {
 		goto out;
 	}
 
 	/* Check index record size. */
 	if ((boot->index_size < 0 &&
-		 SECTOR_SIZE > (2U << (-boot->index_size))) ||
-		(boot->index_size >= 0 && !is_power_of_2(boot->index_size))) {
+	     SECTOR_SIZE > (2U << (-boot->index_size))) ||
+	    (boot->index_size >= 0 && !is_power_of_2(boot->index_size))) {
 		goto out;
 	}
 
@@ -796,6 +762,9 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
 		dev_size += sector_size - 1;
 	}
 
+	sbi->cluster_size = boot_sector_size * sct_per_clst;
+	sbi->cluster_bits = blksize_bits(sbi->cluster_size);
+
 	sbi->mft.lbo = mlcn << sbi->cluster_bits;
 	sbi->mft.lbo2 = mlcn2 << sbi->cluster_bits;
 
@@ -816,9 +785,9 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
 	sbi->cluster_mask = sbi->cluster_size - 1;
 	sbi->cluster_mask_inv = ~(u64)sbi->cluster_mask;
 	sbi->record_size = record_size = boot->record_size < 0
-		? 1 << (-boot->record_size)
-		: (u32)boot->record_size
-		  << sbi->cluster_bits;
+						 ? 1 << (-boot->record_size)
+						 : (u32)boot->record_size
+							   << sbi->cluster_bits;
 
 	if (record_size > MAXIMUM_BYTES_PER_MFT || record_size < SECTOR_SIZE)
 		goto out;
@@ -832,8 +801,8 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
 		ALIGN(sizeof(enum ATTR_TYPE), 8);
 
 	sbi->index_size = boot->index_size < 0
-		? 1u << (-boot->index_size)
-		: (u32)boot->index_size << sbi->cluster_bits;
+				  ? 1u << (-boot->index_size)
+				  : (u32)boot->index_size << sbi->cluster_bits;
 
 	sbi->volume.ser_num = le64_to_cpu(boot->serial_num);
 
@@ -902,6 +871,13 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
 	sb->s_maxbytes = 0xFFFFFFFFull << sbi->cluster_bits;
 #endif
 
+	/*
+	 * Compute the MFT zone at two steps.
+	 * It would be nice if we are able to allocate 1/8 of
+	 * total clusters for MFT but not more then 512 MB.
+	 */
+	sbi->zone_max = min_t(CLST, 0x20000000 >> sbi->cluster_bits, clusters >> 3);
+
 	err = 0;
 
 out:
-- 
2.49.0




More information about the lvc-project mailing list