* [PATCH 5.15.y] fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
@ 2025-03-09 14:54 Miguel García
2025-03-10 2:14 ` Sasha Levin
0 siblings, 1 reply; 8+ messages in thread
From: Miguel García @ 2025-03-09 14:54 UTC (permalink / raw)
To: stable; +Cc: skhan
[-- Attachment #1: Type: text/plain, Size: 0 bytes --]
[-- Attachment #2: 0001-fs-ntfs3-Fix-shift-out-of-bounds-in-ntfs_fill_super.patch --]
[-- Type: text/x-diff, Size: 6112 bytes --]
From 2a433fb910874180a57199f31cf01f65e27dcb00 Mon Sep 17 00:00:00 2001
From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Date: Fri, 30 Jun 2023 16:25:25 +0400
Subject: [PATCH 5.15.y] fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
commit 91a4b1ee78cb ("fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super")
This patch is a backport and fixes an UBSAN warning about shift-out-of-bounds in
ntfs_fill_super() function of the NTFS3 driver. The original code
incorrectly calculated MFT record size, causing undefined behavior
when performing bit shifts with values that exceed type limits.
The fix has been verified by executing the syzkaller reproducer test case.
After applying this patch, the system successfully handles the test case
without kernel panic or UBSAN warnings.
Bug: https://syzkaller.appspot.com/bug?extid=010986becd65dbf9464b
Reported-by: syzbot+010986becd65dbf9464b@syzkaller.appspotmail.com
Cc: <stable@vger.kernel.org>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Miguel Garcia Roman <miguelgarciaroman8@gmail.com>
(cherry picked from commit 91a4b1ee78cb100b19b70f077c247f211110348f)
---
fs/ntfs3/ntfs_fs.h | 2 ++
fs/ntfs3/super.c | 63 +++++++++++++++++++++++++++++++++++-----------
2 files changed, 50 insertions(+), 15 deletions(-)
diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
index 7b46926e920c..c5ef0e0cdf59 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -43,9 +43,11 @@ 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 78b086527331..abab388e413f 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,15 +733,49 @@ 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))) {
+ 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);
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;
}
@@ -762,9 +796,6 @@ 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;
@@ -785,9 +816,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;
@@ -801,8 +832,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);
@@ -879,6 +910,8 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
return err;
}
+
+
/*
* ntfs_fill_super - Try to mount.
*/
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5.15.y] fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
@ 2025-03-09 14:56 Miguel García
2025-03-10 2:14 ` Sasha Levin
2025-03-10 16:21 ` Greg KH
0 siblings, 2 replies; 8+ messages in thread
From: Miguel García @ 2025-03-09 14:56 UTC (permalink / raw)
To: stable
Cc: skhan, Konstantin Komarov, syzbot+010986becd65dbf9464b,
Miguel Garcia Roman
From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
commit 91a4b1ee78cb ("fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super")
This patch is a backport and fixes an UBSAN warning about shift-out-of-bounds in
ntfs_fill_super() function of the NTFS3 driver. The original code
incorrectly calculated MFT record size, causing undefined behavior
when performing bit shifts with values that exceed type limits.
The fix has been verified by executing the syzkaller reproducer test case.
After applying this patch, the system successfully handles the test case
without kernel panic or UBSAN warnings.
Bug: https://syzkaller.appspot.com/bug?extid=010986becd65dbf9464b
Reported-by: syzbot+010986becd65dbf9464b@syzkaller.appspotmail.com
Cc: <stable@vger.kernel.org>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Miguel Garcia Roman <miguelgarciaroman8@gmail.com>
(cherry picked from commit 91a4b1ee78cb100b19b70f077c247f211110348f)
---
fs/ntfs3/ntfs_fs.h | 2 ++
fs/ntfs3/super.c | 63 +++++++++++++++++++++++++++++++++++-----------
2 files changed, 50 insertions(+), 15 deletions(-)
diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
index 7b46926e920c..c5ef0e0cdf59 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -43,9 +43,11 @@ 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 78b086527331..abab388e413f 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,15 +733,49 @@ 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))) {
+ 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);
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;
}
@@ -762,9 +796,6 @@ 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;
@@ -785,9 +816,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;
@@ -801,8 +832,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);
@@ -879,6 +910,8 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
return err;
}
+
+
/*
* ntfs_fill_super - Try to mount.
*/
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 5.15.y] fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
2025-03-09 14:54 [PATCH 5.15.y] fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super Miguel García
@ 2025-03-10 2:14 ` Sasha Levin
0 siblings, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2025-03-10 2:14 UTC (permalink / raw)
To: stable, miguelgarciaroman8; +Cc: Sasha Levin
[ Sasha's backport helper bot ]
Hi,
Summary of potential issues:
⚠️ Found matching upstream commit but patch is missing proper reference to it
Found matching upstream commit: 91a4b1ee78cb100b19b70f077c247f211110348f
WARNING: Author mismatch between patch and found commit:
Backport author: Miguel =?iso-8859-1?Q?Garc=EDa?=<miguelgarciaroman8@gmail.com>
Commit author: Konstantin Komarov<almaz.alexandrovich@paragon-software.com>
Status in newer kernel trees:
6.13.y | Present (exact SHA1)
6.12.y | Present (exact SHA1)
6.6.y | Present (exact SHA1)
6.1.y | Not found
5.4.y | Not found
Note: The patch differs from the upstream commit:
---
1: 91a4b1ee78cb1 < -: ------------- fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
-: ------------- > 1: da31bbdbd8964 fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
---
Results of testing on various branches:
| Branch | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-5.15.y | Success | Success |
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 5.15.y] fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
2025-03-09 14:56 Miguel García
@ 2025-03-10 2:14 ` Sasha Levin
2025-03-10 8:48 ` Miguel García
2025-03-10 16:21 ` Greg KH
1 sibling, 1 reply; 8+ messages in thread
From: Sasha Levin @ 2025-03-10 2:14 UTC (permalink / raw)
To: stable, miguelgarciaroman8; +Cc: Sasha Levin
[ Sasha's backport helper bot ]
Hi,
Summary of potential issues:
⚠️ Found matching upstream commit but patch is missing proper reference to it
Found matching upstream commit: 91a4b1ee78cb100b19b70f077c247f211110348f
WARNING: Author mismatch between patch and found commit:
Backport author: =?UTF-8?q?Miguel=20Garc=C3=ADa?=<miguelgarciaroman8@gmail.com>
Commit author: Konstantin Komarov<almaz.alexandrovich@paragon-software.com>
Status in newer kernel trees:
6.13.y | Present (exact SHA1)
6.12.y | Present (exact SHA1)
6.6.y | Present (exact SHA1)
6.1.y | Not found
5.4.y | Not found
Note: The patch differs from the upstream commit:
---
1: 91a4b1ee78cb1 < -: ------------- fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
-: ------------- > 1: c9056c5e43e40 fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
---
Results of testing on various branches:
| Branch | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-5.15.y | Success | Success |
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 5.15.y] fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
2025-03-10 2:14 ` Sasha Levin
@ 2025-03-10 8:48 ` Miguel García
2025-03-10 16:20 ` Greg KH
2025-03-13 9:08 ` Sasha Levin
0 siblings, 2 replies; 8+ messages in thread
From: Miguel García @ 2025-03-10 8:48 UTC (permalink / raw)
To: stable
Cc: skhan, Konstantin Komarov, syzbot+010986becd65dbf9464b,
Miguel Garcia Roman
From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
commit 91a4b1ee78cb100b19b70f077c247f211110348f upstream.
This patch is a backport and fixes an UBSAN warning about shift-out-of-bounds in
ntfs_fill_super() function of the NTFS3 driver. The original code
incorrectly calculated MFT record size, causing undefined behavior
when performing bit shifts with values that exceed type limits.
The fix has been verified by executing the syzkaller reproducer test case.
After applying this patch, the system successfully handles the test case
without kernel panic or UBSAN warnings.
Bug: https://syzkaller.appspot.com/bug?extid=010986becd65dbf9464b
Reported-by: syzbot+010986becd65dbf9464b@syzkaller.appspotmail.com
Cc: <stable@vger.kernel.org>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Miguel Garcia Roman <miguelgarciaroman8@gmail.com>
(cherry picked from commit 91a4b1ee78cb100b19b70f077c247f211110348f)
---
fs/ntfs3/ntfs_fs.h | 2 ++
fs/ntfs3/super.c | 63 +++++++++++++++++++++++++++++++++++-----------
2 files changed, 50 insertions(+), 15 deletions(-)
diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
index 7b46926e920c..c5ef0e0cdf59 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -43,9 +43,11 @@ 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 78b086527331..abab388e413f 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,15 +733,49 @@ 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))) {
+ 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);
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;
}
@@ -762,9 +796,6 @@ 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;
@@ -785,9 +816,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;
@@ -801,8 +832,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);
@@ -879,6 +910,8 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
return err;
}
+
+
/*
* ntfs_fill_super - Try to mount.
*/
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 5.15.y] fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
2025-03-10 8:48 ` Miguel García
@ 2025-03-10 16:20 ` Greg KH
2025-03-13 9:08 ` Sasha Levin
1 sibling, 0 replies; 8+ messages in thread
From: Greg KH @ 2025-03-10 16:20 UTC (permalink / raw)
To: Miguel García
Cc: stable, skhan, Konstantin Komarov, syzbot+010986becd65dbf9464b
On Mon, Mar 10, 2025 at 09:48:21AM +0100, Miguel García wrote:
> From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
>
> commit 91a4b1ee78cb100b19b70f077c247f211110348f upstream.
>
> This patch is a backport and fixes an UBSAN warning about shift-out-of-bounds in
> ntfs_fill_super() function of the NTFS3 driver. The original code
> incorrectly calculated MFT record size, causing undefined behavior
> when performing bit shifts with values that exceed type limits.
>
> The fix has been verified by executing the syzkaller reproducer test case.
> After applying this patch, the system successfully handles the test case
> without kernel panic or UBSAN warnings.
>
> Bug: https://syzkaller.appspot.com/bug?extid=010986becd65dbf9464b
> Reported-by: syzbot+010986becd65dbf9464b@syzkaller.appspotmail.com
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
> Signed-off-by: Miguel Garcia Roman <miguelgarciaroman8@gmail.com>
> (cherry picked from commit 91a4b1ee78cb100b19b70f077c247f211110348f)
> ---
> fs/ntfs3/ntfs_fs.h | 2 ++
> fs/ntfs3/super.c | 63 +++++++++++++++++++++++++++++++++++-----------
> 2 files changed, 50 insertions(+), 15 deletions(-)
Why was this resent?
confused,
greg k-h
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 5.15.y] fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
2025-03-09 14:56 Miguel García
2025-03-10 2:14 ` Sasha Levin
@ 2025-03-10 16:21 ` Greg KH
1 sibling, 0 replies; 8+ messages in thread
From: Greg KH @ 2025-03-10 16:21 UTC (permalink / raw)
To: Miguel García
Cc: stable, skhan, Konstantin Komarov, syzbot+010986becd65dbf9464b
On Sun, Mar 09, 2025 at 03:56:36PM +0100, Miguel García wrote:
> From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
>
> commit 91a4b1ee78cb ("fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super")
>
> This patch is a backport and fixes an UBSAN warning about shift-out-of-bounds in
> ntfs_fill_super() function of the NTFS3 driver. The original code
> incorrectly calculated MFT record size, causing undefined behavior
> when performing bit shifts with values that exceed type limits.
>
> The fix has been verified by executing the syzkaller reproducer test case.
> After applying this patch, the system successfully handles the test case
> without kernel panic or UBSAN warnings.
>
> Bug: https://syzkaller.appspot.com/bug?extid=010986becd65dbf9464b
> Reported-by: syzbot+010986becd65dbf9464b@syzkaller.appspotmail.com
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
> Signed-off-by: Miguel Garcia Roman <miguelgarciaroman8@gmail.com>
> (cherry picked from commit 91a4b1ee78cb100b19b70f077c247f211110348f)
> ---
> fs/ntfs3/ntfs_fs.h | 2 ++
> fs/ntfs3/super.c | 63 +++++++++++++++++++++++++++++++++++-----------
> 2 files changed, 50 insertions(+), 15 deletions(-)
We need a 6.1.y version of this first. Please submit that first and
then resend this for older kernels.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 5.15.y] fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
2025-03-10 8:48 ` Miguel García
2025-03-10 16:20 ` Greg KH
@ 2025-03-13 9:08 ` Sasha Levin
1 sibling, 0 replies; 8+ messages in thread
From: Sasha Levin @ 2025-03-13 9:08 UTC (permalink / raw)
To: stable; +Cc: Miguel García, Sasha Levin
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected.
No action required from the submitter.
The upstream commit SHA1 provided is correct: 91a4b1ee78cb100b19b70f077c247f211110348f
WARNING: Author mismatch between patch and upstream commit:
Backport author: =?UTF-8?q?Miguel=20Garc=C3=ADa?=<miguelgarciaroman8@gmail.com>
Commit author: Konstantin Komarov<almaz.alexandrovich@paragon-software.com>
Status in newer kernel trees:
6.13.y | Present (exact SHA1)
6.12.y | Present (exact SHA1)
6.6.y | Present (exact SHA1)
6.1.y | Not found
Note: The patch differs from the upstream commit:
---
1: 91a4b1ee78cb1 < -: ------------- fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
-: ------------- > 1: eda5808d02243 fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super
---
Results of testing on various branches:
| Branch | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-5.15.y | Success | Success |
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-03-13 9:08 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-09 14:54 [PATCH 5.15.y] fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super Miguel García
2025-03-10 2:14 ` Sasha Levin
-- strict thread matches above, loose matches on Subject: below --
2025-03-09 14:56 Miguel García
2025-03-10 2:14 ` Sasha Levin
2025-03-10 8:48 ` Miguel García
2025-03-10 16:20 ` Greg KH
2025-03-13 9:08 ` Sasha Levin
2025-03-10 16:21 ` Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox