Thanks for the feedback :)
Here are the two fixes as proper patches, one per finding.
Patch 1: Adds bounds check in UpdateFileNameRoot and
UpdateFileNameAllocation to prevent 56-byte memmove from overflowing
when e->size is too small.
Patch 2: Validates fname_full_size() against the attribute's actual
res.data_size in ni_remove_name() before copying.
Both pass checkpatch with zero errors and zero warnings.
KRISH JAIN
From ffc37dbfd48020558f278a2fef6fd03dbe117339 Mon Sep 17 00:00:00 2001
From: KRISH JAIN <[email protected]>
Date: Tue, 18 Aug 2026 23:39:59 +0530
Subject: [PATCH 1/2] ntfs3: add bounds check to prevent oob write in
UpdateFileNameRoot
The UpdateFileNameRoot and UpdateFileNameAllocation handlers in
do_action() perform a 56-byte memmove into an index entry's embedded
ATTR_FILE_NAME structure without verifying that the entry is large
enough to contain the write. If e->size is smaller than the required
80 bytes (sizeof(NTFS_DE) + offsetof(ATTR_FILE_NAME, dup) +
sizeof(NTFS_DUP_INFO)), the memmove overflows into adjacent slab
objects in kmalloc-1024.
Add a bounds check before both memmove calls to validate that e->size
is sufficient, marking the volume dirty and aborting replay if not.
Fixes: 8d3ae59288f1 ("Linux 7.2")
Signed-off-by: KRISH JAIN <[email protected]>
Assisted-by: Claude:Opus4.6
---
fs/ntfs3/fslog.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
index f038c799e..c32b59f4e 100644
--- a/fs/ntfs3/fslog.c
+++ b/fs/ntfs3/fslog.c
@@ -3520,8 +3520,13 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe,
}
e = Add2Ptr(attr, le16_to_cpu(lrh->attr_off));
+ if (le16_to_cpu(e->size) <
+ sizeof(struct NTFS_DE) +
+ offsetof(struct ATTR_FILE_NAME, dup) +
+ sizeof(fname->dup))
+ goto dirty_vol;
fname = (struct ATTR_FILE_NAME *)(e + 1);
- memmove(&fname->dup, data, sizeof(fname->dup)); //
+ memmove(&fname->dup, data, sizeof(fname->dup));
mi->dirty = true;
break;
@@ -3706,6 +3711,11 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe,
goto dirty_vol;
}
+ if (le16_to_cpu(e->size) <
+ sizeof(struct NTFS_DE) +
+ offsetof(struct ATTR_FILE_NAME, dup) +
+ sizeof(fname->dup))
+ goto dirty_vol;
fname = (struct ATTR_FILE_NAME *)(e + 1);
memmove(&fname->dup, data, sizeof(fname->dup));
--
2.53.0
From df143212211876f87a7253b555cee28435575431 Mon Sep 17 00:00:00 2001
From: KRISH JAIN <[email protected]>
Date: Tue, 18 Aug 2026 23:40:10 +0530
Subject: [PATCH 2/2] ntfs3: validate fname size against resident data in
ni_remove_name
In ni_remove_name(), fname_full_size() computes the copy length from
the untrusted on-disk name_len field, which can be up to 255 (yielding
576 bytes). If name_len is larger than the attribute's actual resident
data size, the subsequent memcpy reads past the end of the attribute
buffer.
Add a check that fname_full_size() does not exceed the attribute's
res.data_size before performing the copy.
Fixes: 8d3ae59288f1 ("Linux 7.2")
Signed-off-by: KRISH JAIN <[email protected]>
Assisted-by: Claude:Opus4.6
---
fs/ntfs3/frecord.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
index 2b49bc077..42627a5f2 100644
--- a/fs/ntfs3/frecord.c
+++ b/fs/ntfs3/frecord.c
@@ -2653,6 +2653,10 @@ int ni_remove_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
fname = ni_fname_type(ni, name_type, &mi, &le);
if (fname) {
u16 de2_key_size = fname_full_size(fname);
+ struct ATTRIB *attr = attr_from_name(fname);
+
+ if (de2_key_size > le32_to_cpu(attr->res.data_size))
+ return -EINVAL;
*de2 = Add2Ptr(de, 1024);
(*de2)->key_size = cpu_to_le16(de2_key_size);
--
2.53.0
---
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.