NTFS3 file system kernel mode driver
 help / color / mirror / Atom feed
* [PATCH] fs/ntfs3: validate target_attr in log_replay()
@ 2026-09-01 17:49 Cen Zhang (Microsoft Security FORGE Labs)
  2026-09-02  5:53 ` Greg KH
  0 siblings, 1 reply; 2+ messages in thread
From: Cen Zhang (Microsoft Security FORGE Labs) @ 2026-09-01 17:49 UTC (permalink / raw)
  To: almaz.alexandrovich
  Cc: ntfs3, linux-kernel, stable, AutonomousCodeSecurity, xmei5,
	tgopinath, kys, Cen Zhang (Microsoft Security FORGE Labs)

log_replay() treats lrh->target_attr as a byte offset to an
OPEN_ATTR_ENRTY in the open-attribute restart table. A valid offset is
the table header size plus an integral number of entries. The redo
lookup checks only target_attr < bytes_per_rt(oatbl); its earlier
alignment check subtracts the header size without first checking the
lower bound, so the subtraction can wrap.

The undo lookup has no table-bound check, and its earlier alignment
check is skipped when lcns_follow is zero. Unlike the redo lookup, it
also does not reject unallocated entries or NULL entry pointers.

A crafted $LogFile can therefore point into the table header, the middle
of an entry, or past the table and trigger an out-of-bounds access.

BUG: KASAN: slab-out-of-bounds in log_replay+0x7d44/0x9d80
  fs/ntfs3/fslog.c:5235 log_replay()
  ntfs_loadlog_and_replay()
  ntfs_fill_super()
  path_mount()

Add rstbl_entry_valid() to require a nonzero entry size and an offset
between the table header and end that is aligned to the entry size. Use
it before both lookups, and make the undo lookup match the redo lookup
by rejecting unallocated entries and NULL entry pointers. Skip
targetless records with no LCN work before the lookup so their unused
target_attr is not subjected to the new validation.

Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
Reported-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
Cc: AutonomousCodeSecurity@microsoft.com
Cc: stable@vger.kernel.org
Signed-off-by: Cen Zhang (Microsoft Security FORGE Labs) <cenzhang@linux.microsoft.com>
---
 fs/ntfs3/fslog.c | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
index ed50c1d0c23e..1ddff43dbe87 100644
--- a/fs/ntfs3/fslog.c
+++ b/fs/ntfs3/fslog.c
@@ -384,6 +384,14 @@ static inline u32 bytes_per_rt(const struct RESTART_TABLE *rt)
 	       sizeof(struct RESTART_TABLE);
 }
 
+static inline bool rstbl_entry_valid(const struct RESTART_TABLE *rt, u32 off)
+{
+	u16 size = le16_to_cpu(rt->size);
+
+	return size && off >= sizeof(*rt) && off < bytes_per_rt(rt) &&
+	       !((off - sizeof(*rt)) % size);
+}
+
 /* Log record length. */
 static inline u32 lrh_length(const struct LOG_REC_HDR *lr)
 {
@@ -5086,7 +5094,7 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)
 		goto read_next_log_do_action;
 
 	t16 = le16_to_cpu(lrh->target_attr);
-	if (t16 >= bytes_per_rt(oatbl)) {
+	if (!rstbl_entry_valid(oatbl, t16)) {
 		err = -EINVAL;
 		goto out;
 	}
@@ -5231,8 +5239,29 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)
 	if (lrh->undo_op == cpu_to_le16(Noop))
 		goto read_next_log_undo_action;
 
-	oe = Add2Ptr(oatbl, le16_to_cpu(lrh->target_attr));
+	/* Skip records with neither target nor LCN work. */
+	t16 = le16_to_cpu(lrh->undo_op);
+	if (!lrh->lcns_follow && !is_target_required(t16) &&
+	    can_skip_action(t16))
+		goto read_next_log_undo_action;
+
+	t16 = le16_to_cpu(lrh->target_attr);
+	if (!rstbl_entry_valid(oatbl, t16)) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	oe = Add2Ptr(oatbl, t16);
+	if (oe->next != RESTART_ENTRY_ALLOCATED_LE) {
+		err = -EINVAL;
+		goto out;
+	}
+
 	oa = oe->ptr;
+	if (!oa) {
+		err = -EINVAL;
+		goto out;
+	}
 
 	t16 = le16_to_cpu(lrh->lcns_follow);
 	if (!t16)

base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-09-02  5:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-01 17:49 [PATCH] fs/ntfs3: validate target_attr in log_replay() Cen Zhang (Microsoft Security FORGE Labs)
2026-09-02  5:53 ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox