ntfs-3g-ntfsprogs: fix CVE-2026-46572 and CVE-2026-42617

This patch applies the upstream fixes shown in [1], [2], and [3].
The NVD records describing the vulnerabilities are referenced in
[4] and [5].

[1] https://github.com/tuxera/ntfs-3g/commit/2ead8a3ccf940c0219ffba587fab54e21462b3a5
[2] https://github.com/tuxera/ntfs-3g/commit/dfd1a7c6eb23a22238ec193451fa59c989b4381f
[3] https://github.com/tuxera/ntfs-3g/commit/edf2b892356684ca8f2fc5898943c7a9b90ffb80
[4] https://nvd.nist.gov/vuln/detail/CVE-2026-46572
[5] https://nvd.nist.gov/vuln/detail/CVE-2026-42617

Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
Darsh Kelaiya authored and Anuj Mittal committed 2026-10-29 10:19:01 +05:30
1 parent 4202adbfe6
commit 1e0b8b62e2
4 files changed
+208

No files matched your search

@@ -0,0 +1,66 @@
From 7a3fccddc2bca7609fd6597fcb6ea8a42a258937 Mon Sep 17 00:00:00 2001
From: Erik Larsson <erik@tuxera.com>
Date: Fri, 24 Apr 2026 13:00:30 +0300
Subject: [PATCH] index.c: Validate the size of data copied from root to index
block.
If the last entry extends beyond the index block size, we could copy
more bytes than allocated into the index block, overflowing its
allocation. Fixed by adding a bounds check prior to the memcpy, emitting
an error message and returning NULL with errno == EIO as this is an
inconsistency.
Thanks to Alexandro Calo' from Nozomi Networks Labs for reporting this
issue.
CVE: CVE-2026-46572 CVE-2026-42617
Upstream-Status: Backport [https://github.com/tuxera/ntfs-3g/commit/2ead8a3ccf940c0219ffba587fab54e21462b3a5]
(cherry picked from commit 2ead8a3ccf940c0219ffba587fab54e21462b3a5)
Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
---
libntfs-3g/index.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/libntfs-3g/index.c b/libntfs-3g/index.c
index e48d6aaf..2739594b 100644
--- a/libntfs-3g/index.c
+++ b/libntfs-3g/index.c
@@ -1091,14 +1091,16 @@ out:
static INDEX_BLOCK *ntfs_ir_to_ib(INDEX_ROOT *ir, VCN ib_vcn)
{
+ u32 ib_size;
INDEX_BLOCK *ib;
INDEX_ENTRY *ie_last;
char *ies_start, *ies_end;
int i;
ntfs_log_trace("Entering\n");
-
- ib = ntfs_ib_alloc(ib_vcn, le32_to_cpu(ir->index_block_size), LEAF_NODE);
+
+ ib_size = le32_to_cpu(ir->index_block_size);
+ ib = ntfs_ib_alloc(ib_vcn, ib_size, LEAF_NODE);
if (!ib)
return NULL;
@@ -1110,6 +1112,18 @@ static INDEX_BLOCK *ntfs_ir_to_ib(INDEX_ROOT *ir, VCN ib_vcn)
* as well, which can never have any data.
*/
i = (char *)ie_last - ies_start + le16_to_cpu(ie_last->length);
+
+ if (offsetof(INDEX_BLOCK, index) + le32_to_cpu(ib->index.entries_offset)
+ + i > ib_size)
+ {
+ ntfs_log_error("Last entry in index root overflows the index "
+ "block size: %d (index block size: %lu)\n",
+ i, (unsigned long)ib_size);
+ free(ib);
+ errno = EIO;
+ return NULL;
+ }
+
memcpy(ntfs_ie_get_first(&ib->index), ies_start, i);
ib->index.ih_flags = ir->index.ih_flags;
@@ -0,0 +1,104 @@
From 51475eab2d2a559e10a8d3772d56444feffc13a4 Mon Sep 17 00:00:00 2001
From: Rakesh Pandit <rakesh@tuxera.com>
Date: Mon, 8 Jun 2026 09:27:45 +0300
Subject: [PATCH] Validate index entry stream while reading from disk.
Add ntfs_ie_stream_inconsistent() to walk the IE stream once and verify
every entry: header fits, length is sane and 8-byte aligned, entry fits,
and the END entry terminates the stream exactly. Call it from
ntfs_attr_inconsistent() for INDEX_ROOT and from
ntfs_index_block_inconsistent() for INDX blocks so callers can rely on
the IE stream being well-formed.
CVE: CVE-2026-46572 CVE-2026-42617
Upstream-Status: Backport [https://github.com/tuxera/ntfs-3g/commit/dfd1a7c6eb23a22238ec193451fa59c989b4381f]
(cherry picked from commit dfd1a7c6eb23a22238ec193451fa59c989b4381f)
Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
---
include/ntfs-3g/index.h | 1 +
libntfs-3g/attrib.c | 3 +++
libntfs-3g/index.c | 37 ++++++++++++++++++++++++++++++++++++-
3 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/include/ntfs-3g/index.h b/include/ntfs-3g/index.h
index d001863a..1d5845d4 100644
--- a/include/ntfs-3g/index.h
+++ b/include/ntfs-3g/index.h
@@ -143,6 +143,7 @@ extern int ntfs_index_block_inconsistent(const INDEX_BLOCK *ib, u32 block_size,
u64 inum, VCN vcn);
extern int ntfs_index_entry_inconsistent(const INDEX_ENTRY *ie,
COLLATION_RULES collation_rule, u64 inum);
+extern int ntfs_ie_stream_inconsistent(const INDEX_HEADER *ih, u64 inum);
extern int ntfs_index_lookup(const void *key, const int key_len,
ntfs_index_context *ictx) __attribute_warn_unused_result__;
diff --git a/libntfs-3g/attrib.c b/libntfs-3g/attrib.c
index efb91943..ad9ebceb 100644
--- a/libntfs-3g/attrib.c
+++ b/libntfs-3g/attrib.c
@@ -3542,6 +3542,9 @@ int ntfs_attr_inconsistent(const ATTR_RECORD *a, const MFT_REF mref)
(long long)inum);
errno = EIO;
ret = -1;
+ } else if (ntfs_ie_stream_inconsistent(&ir->index, inum)) {
+ errno = EIO;
+ ret = -1;
}
break;
case AT_STANDARD_INFORMATION :
diff --git a/libntfs-3g/index.c b/libntfs-3g/index.c
index 2739594b..c9651a62 100644
--- a/libntfs-3g/index.c
+++ b/libntfs-3g/index.c
@@ -504,6 +504,8 @@ int ntfs_index_block_inconsistent(const INDEX_BLOCK *ib, u32 block_size,
(unsigned long long)inum);
return -1;
}
+ if (ntfs_ie_stream_inconsistent(&ib->index, inum))
+ return -1;
return (0);
}
@@ -560,7 +562,40 @@ int ntfs_index_entry_inconsistent(const INDEX_ENTRY *ie,
return (ret);
}
-/**
+int ntfs_ie_stream_inconsistent(const INDEX_HEADER *ih, u64 inum)
+{
+ const u8 *ies_start = (const u8 *)ih + le32_to_cpu(ih->entries_offset);
+ const u8 *ies_end = (const u8 *)ih + le32_to_cpu(ih->index_length);
+ const u8 *ie;
+
+ ntfs_log_trace("Entering\n");
+
+ for (ie = ies_start; ie < ies_end; ) {
+ u32 len;
+ const INDEX_ENTRY *ent = (const INDEX_ENTRY *)ie;
+
+ if ((size_t)(ies_end - ie) < sizeof(INDEX_ENTRY_HEADER))
+ goto err;
+ len = le16_to_cpu(ent->length);
+ if (len < sizeof(INDEX_ENTRY_HEADER) || (len & 7))
+ goto err;
+ if ((size_t)(ies_end - ie) < len)
+ goto err;
+ if (ent->ie_flags & INDEX_ENTRY_END) {
+ /* END must terminate the stream exactly. */
+ if (ie + len != ies_end)
+ goto err;
+ return 0;
+ }
+ ie += len;
+ }
+err:
+ ntfs_log_error("Corrupt index entry stream in inode %lld\n",
+ (long long)inum);
+ return -1;
+}
+
+/**
* Find a key in the index block.
*
* Return values:
@@ -0,0 +1,35 @@
From c8630e735204fd4ed4b49c4dc315716664b965c1 Mon Sep 17 00:00:00 2001
From: Rakesh Pandit <rakesh@tuxera.com>
Date: Mon, 8 Jun 2026 09:57:11 +0300
Subject: [PATCH] Validate INDEX_ROOT.index_block_size from disk.
Reject INDEX_ROOT attributes whose index_block_size is smaller than
NTFS_BLOCK_SIZE or not a power of two. Same rule the driver already
applies at libntfs-3g/dir.c.
Thanks to Alexandro Calo' from Nozomi Networks Labs for the report.
CVE: CVE-2026-46572 CVE-2026-42617
Upstream-Status: Backport [https://github.com/tuxera/ntfs-3g/commit/edf2b892356684ca8f2fc5898943c7a9b90ffb80]
(cherry picked from commit edf2b892356684ca8f2fc5898943c7a9b90ffb80)
Signed-off-by: Darsh Kelaiya <dkelaiya@cisco.com>
---
libntfs-3g/attrib.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/libntfs-3g/attrib.c b/libntfs-3g/attrib.c
index ad9ebceb..cfc2446e 100644
--- a/libntfs-3g/attrib.c
+++ b/libntfs-3g/attrib.c
@@ -3528,6 +3528,10 @@ int ntfs_attr_inconsistent(const ATTR_RECORD *a, const MFT_REF mref)
if (a->non_resident
|| (le32_to_cpu(a->value_length)
< offsetof(INDEX_ROOT, index.reserved))
+ || (le32_to_cpu(ir->index_block_size)
+ < NTFS_BLOCK_SIZE)
+ || (le32_to_cpu(ir->index_block_size)
+ & (le32_to_cpu(ir->index_block_size) - 1))
|| (le32_to_cpu(ir->index.entries_offset)
< sizeof(INDEX_HEADER))
|| (le32_to_cpu(ir->index.index_length)
@@ -9,6 +9,9 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \
SRC_URI = "git://github.com/tuxera/ntfs-3g;protocol=https;branch=edge;tag=${PV} \
file://0001-libntfs-3g-Makefile.am-fix-install-failed-while-host.patch \
file://0001-unistr.c-Fix-use-after-free-in-ntfs_uppercase_mbs.patch \
file://CVE-2026-46572_CVE-2026-42617_p1.patch \
file://CVE-2026-46572_CVE-2026-42617_p2.patch \
file://CVE-2026-46572_CVE-2026-42617_p3.patch \
"
SRCREV = "78414d93613532fd82f3a82aba5d4a1c32898781"