<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/fs/ntfs3, branch v5.15.213</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v5.15.213</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v5.15.213'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2026-07-24T13:51:49+00:00</updated>
<entry>
<title>ntfs3: fix out-of-bounds read in decompress_lznt</title>
<updated>2026-07-24T13:51:49+00:00</updated>
<author>
<name>Tristan Madani</name>
<email>tristan@talencesecurity.com</email>
</author>
<published>2026-04-18T13:11:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=1113fa5b01a47a1a4cdbb9c695197ca6215f02a8'/>
<id>urn:sha1:1113fa5b01a47a1a4cdbb9c695197ca6215f02a8</id>
<content type='text'>
commit 7160a57192fb16d7a6fa9b7f5c7ac341d2444a89 upstream.

decompress_lznt() does not validate array index bounds before accessing
the decompression table. A corrupted NTFS3 image with invalid compressed
data can trigger an out-of-bounds read.

Add index bounds checking to prevent the OOB access.

Reported-by: syzbot+39b2fb0f2638669008ec@syzkaller.appspotmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani &lt;tristan@talencesecurity.com&gt;
Signed-off-by: Konstantin Komarov &lt;almaz.alexandrovich@paragon-software.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>ntfs3: bound to_move in indx_insert_into_root before hdr_insert_head</title>
<updated>2026-07-24T13:51:49+00:00</updated>
<author>
<name>Michael Bommarito</name>
<email>michael.bommarito@gmail.com</email>
</author>
<published>2026-04-17T23:33:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=0af83b8155cc848e9f5d2c36e20a70d024214649'/>
<id>urn:sha1:0af83b8155cc848e9f5d2c36e20a70d024214649</id>
<content type='text'>
commit 9b6926ac9c970ae0b2c2fe6289b16e9aa10b6a67 upstream.

indx_insert_into_root() promotes a full resident $INDEX_ROOT into
$INDEX_ALLOCATION and copies all non-last resident root entries into
a newly allocated INDEX_BUFFER via hdr_insert_head(). The source
byte count 'to_move' is summed from the on-disk resident entry sizes
and is independent of the destination buffer size, which comes from
root-&gt;index_block_size (via indx-&gt;index_bits).

A crafted NTFS image that keeps a valid, full resident root but
shrinks root-&gt;index_block_size down to 512 after the root has been
populated makes hdr_insert_head() memcpy attacker-controlled resident
entry bytes past the end of the kmalloc(1u &lt;&lt; indx-&gt;index_bits)
allocation returned by indx_new(). For a 512-byte destination and a
resident root whose non-last entries total 560 bytes, the memcpy
overruns by 120 bytes and a following memmove extends the highest
written offset to 136 bytes past the allocation. The overflow bytes
are a direct copy of on-disk entries (via kmemdup), so they are
fully attacker-controlled.

The write is reachable from unprivileged open(O_CREAT) on a mounted
crafted NTFS image: a single sufficiently long create in a directory
whose resident root is already full forces root promotion and
triggers the copy.

This is a controlled out-of-bounds write of 120-136 bytes past a
kmalloc(index_block_size) allocation, with attacker-controlled
content. It is a bounded adjacent-heap corruption primitive; it is
not an arbitrary-address write. Successful exploitation into a named
victim object depends on the surrounding slab layout.

Reject the copy at the sink. The destination's INDEX_HDR already
reports hdr_total (the payload capacity of the new buffer) and
hdr_used (the bytes already consumed by the terminal END entry
installed by indx_new()); require that to_move fits in the remaining
payload before calling hdr_insert_head(). On mismatch, fail with
-EINVAL and mark the filesystem as having a detected on-disk
inconsistency, which is the same behaviour as the surrounding
validation in this function.

Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Michael Bommarito &lt;michael.bommarito@gmail.com&gt;
Signed-off-by: Konstantin Komarov &lt;almaz.alexandrovich@paragon-software.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>ntfs3: cap RESTART_TABLE free-chain walker at rt-&gt;used</title>
<updated>2026-07-24T13:51:49+00:00</updated>
<author>
<name>Michael Bommarito</name>
<email>michael.bommarito@gmail.com</email>
</author>
<published>2026-05-17T23:41:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=8128bec895075253c779d67afdc90ae513265fca'/>
<id>urn:sha1:8128bec895075253c779d67afdc90ae513265fca</id>
<content type='text'>
commit 9611f644302c07d21bc8af97e3e06a3d30064253 upstream.

A crafted NTFS3 disk image triggers an in-kernel infinite loop at
mount time, hanging the mounting thread and firing the soft-lockup
watchdog within ~22s on multi-CPU hosts (panic with
kernel.softlockup_panic=1).  The bug is reachable from desktop USB
auto-mount on distributions where udisks2 routes the NTFS signature
to the in-tree ntfs3 driver (Arch family and an increasing fraction
of Fedora / openSUSE / RHEL deployments); CAP_SYS_ADMIN-class manual
mount elsewhere.

check_rstbl()'s second walker iterates the free-entry singly-linked
list headed by rt-&gt;first_free with no upper bound on iteration count:

  for (off = ff; off;) {
      if (off == RESTART_ENTRY_ALLOCATED)
          return false;
      off = le32_to_cpu(*(__le32 *)Add2Ptr(rt, off));
      if (off &gt; ts - sizeof(__le32))
          return false;
  }

The existing guards cover three exits: end-of-list (off == 0), the
in-use marker (off == RESTART_ENTRY_ALLOCATED), and out-of-bounds
(off &gt; ts - sizeof(__le32)).  None of the three prevents an
in-bounds cycle.

A crafted on-disk RESTART_TABLE whose free chain contains a
self-loop or A-&gt;B-&gt;A cycle whose offsets satisfy:

  - in range [sizeof(struct RESTART_TABLE), ts - sizeof(__le32)]
  - (off - sizeof(struct RESTART_TABLE)) % rsize == 0

passes all existing guards and spins the mount-time thread forever.
Reproduced in UML by hand-forging a 2 MB NTFS3 image whose journal
RESTART_TABLE first_free = 0x18 and whose entry at offset 0x18
stores 0x18 as its next pointer; mount of the forged image with
the in-tree ntfs3 driver never returns.

Bound the walker by rt-&gt;used.  Each entry on a legitimate free
chain is unique, and the total slot count is ne = le16_to_cpu
(rt-&gt;used).  A traversal that visits more than ne slots is by
construction malformed; reject it as a corrupt RESTART_TABLE.

After this patch, mount of the forged image returns with -EINVAL
and a log_replay failure message, and mkntfs-produced legitimate
images mount cleanly (verified in the same UML harness).

Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito &lt;michael.bommarito@gmail.com&gt;
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Konstantin Komarov &lt;almaz.alexandrovich@paragon-software.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>fs/ntfs3: bound NTFS_DE view.data_off in UpdateRecordData{Root,Allocation}</title>
<updated>2026-07-24T13:51:49+00:00</updated>
<author>
<name>Michael Bommarito</name>
<email>michael.bommarito@gmail.com</email>
</author>
<published>2026-05-19T09:51:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=b20e5a709d8bd190d6e4645606763c7423e694c1'/>
<id>urn:sha1:b20e5a709d8bd190d6e4645606763c7423e694c1</id>
<content type='text'>
commit 3e127829e57f5190f612412ece4541cb96d5ec7a upstream.

In do_action()'s UpdateRecordDataRoot (fslog.c:3489) and
UpdateRecordDataAllocation (fslog.c:3697) cases, the memmove
destination is `Add2Ptr(e, le16_to_cpu(e-&gt;view.data_off))`,
where e-&gt;view.data_off comes from an on-disk NTFS_DE inside
an INDEX_ROOT or INDEX_BUFFER.  Neither case validates
view.data_off + dlen against e-&gt;size; the existing
check_if_index_root / check_if_alloc_index helpers walk the
entry chain and validate the entry's offset, but not its
internal view fields.

The neighbouring read sites (e.g., fs/ntfs3/index.c when
iterating view entries) check view.data_off + view.data_size
&lt;= e-&gt;size.  Apply the same bound at the two memmove sites.

Reproduced under UML+KASAN on mainline 8d90b09e6741 via
pr_warn-only probe instrumentation: with view.data_off forced
to 0xFFFC, the memmove writes 32 bytes past the end of the
NTFS_DE.

This is similar in shape to Pavitra Jha's 2026-05-02 patch
"fs/ntfs3: prevent oob in case UpdateRecordDataRoot"
(&lt;20260502105008.21827-1-jhapavitra98@gmail.com&gt;) which
proposes calling ntfs3_bad_de_range(); that helper does not
exist in mainline.  This patch uses inline checks.

Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
Cc: stable@vger.kernel.org
Reported-by: Pavitra Jha &lt;jhapavitra98@gmail.com&gt;
Closes: https://lore.kernel.org/ntfs3/20260502105008.21827-1-jhapavitra98@gmail.com/
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Michael Bommarito &lt;michael.bommarito@gmail.com&gt;
Signed-off-by: Konstantin Komarov &lt;almaz.alexandrovich@paragon-software.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>fs/ntfs3: add depth limit to indx_find_buffer to prevent stack overflow</title>
<updated>2026-07-24T13:51:49+00:00</updated>
<author>
<name>Michael Bommarito</name>
<email>michael.bommarito@gmail.com</email>
</author>
<published>2026-04-13T13:31:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=99031d4f63c785d2a985b6a4c64c4256f7117052'/>
<id>urn:sha1:99031d4f63c785d2a985b6a4c64c4256f7117052</id>
<content type='text'>
commit 1ebd684b8f627f75bc3e03f8b2ad8400fd1f02cd upstream.

indx_find_buffer() recursively descends the B+ tree index with no depth
limit.  A crafted NTFS image with circular index node references causes
unbounded recursion, overflowing the kernel stack and panicking the
system.

This is reachable by mounting a malicious NTFS filesystem (e.g. from a
USB drive via desktop automount) and deleting a file whose index entry
triggers the rebalancing fallback path in indx_delete_entry().

Add a depth parameter and bail out with -EINVAL when it reaches the
fnd-&gt;nodes array bound, matching the constraint already enforced by
fnd_push() in indx_find().

The related function indx_find() was previously patched for a similar
infinite-loop issue (commit 1732053c8a6b), but indx_find_buffer() was
missed.

Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Assisted-by: Codex:gpt-5-4
Signed-off-by: Michael Bommarito &lt;michael.bommarito@gmail.com&gt;
Signed-off-by: Konstantin Komarov &lt;almaz.alexandrovich@paragon-software.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>fs/ntfs3: validate lcns_follow in log_replay conversion</title>
<updated>2026-07-24T13:51:49+00:00</updated>
<author>
<name>Konstantin Komarov</name>
<email>almaz.alexandrovich@paragon-software.com</email>
</author>
<published>2026-06-01T08:57:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=ca343a99806b4fc8e27c48f08be3445c5fcd1445'/>
<id>urn:sha1:ca343a99806b4fc8e27c48f08be3445c5fcd1445</id>
<content type='text'>
commit 6a4c53a2e26a865565bd6a460961e8d6fcb32329 upstream.

log_replay() converts DIR_PAGE_ENTRY_32 records into DIR_PAGE_ENTRY
records when replaying version 0 restart tables.

During this conversion, the memmove() length is derived directly from
the on-disk lcns_follow field:

	memmove(&amp;dp-&gt;vcn, &amp;dp0-&gt;vcn_low,
		2 * sizeof(u64) +
				le32_to_cpu(dp-&gt;lcns_follow) * sizeof(u64));

check_rstbl() validates restart table structure, but does not constrain
per-entry lcns_follow values relative to the entry size. A malformed
filesystem image can provide an oversized lcns_follow value, causing
the conversion memmove() to access memory beyond the bounds of the
allocated restart table buffer.

The same field is later used to bound iteration over page_lcns[],
so validating lcns_follow during conversion also prevents downstream
out-of-bounds access from the same malformed metadata.

Compute the maximum valid lcns_follow from the already-validated
restart table entry size and reject entries that exceed this bound.
Reuse the existing t16/t32 scratch variables already declared in
log_replay() to avoid introducing new declarations.

Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
Cc: stable@vger.kernel.org
Signed-off-by: Pavitra Jha &lt;jhapavitra98@gmail.com&gt;
[almaz.alexandrovich@paragon-software.com: fixed the conflicts]
Signed-off-by: Konstantin Komarov &lt;almaz.alexandrovich@paragon-software.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>fs/ntfs3: bound attr_off in UpdateResidentValue against data_off</title>
<updated>2026-07-24T13:51:49+00:00</updated>
<author>
<name>Konstantin Komarov</name>
<email>almaz.alexandrovich@paragon-software.com</email>
</author>
<published>2026-06-02T13:15:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=ab8761676d638c5be170aaf91b7ffdd451236616'/>
<id>urn:sha1:ab8761676d638c5be170aaf91b7ffdd451236616</id>
<content type='text'>
commit d1570c48f49a693974d000251030370ee2e83539 upstream.

In do_action()'s UpdateResidentValue case (fslog.c:3307),
lrh-&gt;attr_off and lrh-&gt;redo_len come from the on-disk LRH.
When they satisfy aoff + dlen &lt; attr-&gt;res.data_off, the
assignment

	attr-&gt;res.data_size = cpu_to_le32(aoff + dlen - data_off);

underflows to ~4 GiB (e.g. 0xFFFFFFF9 when aoff=0x10, dlen=1,
data_off=0x18).  Subsequent code that reads attr-&gt;res.data_size
to walk the resident attribute payload would then read up to
4 GiB past the 1024-byte MFT record allocation.

The existing mi_enum_attr() defense in fs/ntfs3/record.c:287
catches the corrupted data_size on the next attribute walk
and fails the mount, but only on the path that walks all
attributes.  A read site that picks an attribute by name and
reads its data_size without re-validating is not covered.
Validate aoff against data_off and asize at the source.

Reproduced under UML+KASAN on mainline 8d90b09e6741 via
pr_warn-only probe: with aoff=0x10 and data_off=0x18, the
post-assignment data_size is 0xfffffff9 (mount then fails
at -22 from mi_enum_attr).

Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Michael Bommarito &lt;michael.bommarito@gmail.com&gt;
[almaz.alexandrovich@paragon-software.com: clang-formatted the changes]
Signed-off-by: Konstantin Komarov &lt;almaz.alexandrovich@paragon-software.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>fs/ntfs3: bound DeleteIndexEntryAllocation memmove length</title>
<updated>2026-07-24T13:51:49+00:00</updated>
<author>
<name>Konstantin Komarov</name>
<email>almaz.alexandrovich@paragon-software.com</email>
</author>
<published>2026-06-02T13:21:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=c38ed2ab62fab75fd6d0fdc2bee540fbebc7b959'/>
<id>urn:sha1:c38ed2ab62fab75fd6d0fdc2bee540fbebc7b959</id>
<content type='text'>
commit fc4626bb3656362de8b0ecd56605d47a19ec3518 upstream.

In do_action()'s DeleteIndexEntryAllocation case, e-&gt;size comes
from an on-disk INDEX_BUFFER entry.  When e-&gt;size makes
e + e-&gt;size point past hdr + hdr-&gt;used,
PtrOffset(e1, Add2Ptr(hdr, used)) returns a negative ptrdiff_t
that is silently cast to a quasi-infinite size_t when passed
to memmove().  The memmove then walks past the destination
buffer.

The sibling DeleteIndexEntryRoot case at fslog.c:3540-3543
already carries the corresponding guard:

	if (PtrOffset(e1, Add2Ptr(hdr, used)) &lt; esize ||
	    Add2Ptr(e, esize) &gt; Add2Ptr(lrh, rec_len) ||
	    used + esize &gt; le32_to_cpu(hdr-&gt;total)) {
		goto dirty_vol;
	}

Apply the same shape to the allocation-path case.  Also reject
esize == 0: memmove(e, e, ...) is a no-op and leaves
hdr-&gt;used unchanged, hiding a malformed entry from the
existing check_index_header() walk.

Reproduced under UML+KASAN on mainline 8d90b09e6741 by
mounting a crafted NTFS image: the unguarded memmove takes a
length of 0xffffffffffffff00 and the kernel oopses in
memmove+0x81/0x1a0 on the do_action+0x36a2 frame.

Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Michael Bommarito &lt;michael.bommarito@gmail.com&gt;
[almaz.alexandrovich@paragon-software.com: clang-formatted the changes]
Signed-off-by: Konstantin Komarov &lt;almaz.alexandrovich@paragon-software.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>fs/ntfs3: fix syncing wrong inode on DIRSYNC cross-directory rename</title>
<updated>2026-07-24T13:51:49+00:00</updated>
<author>
<name>Zhan Xusheng</name>
<email>zhanxusheng1024@gmail.com</email>
</author>
<published>2026-05-06T07:55:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=fc247511da6be0cb5d803105fade34017ede93b6'/>
<id>urn:sha1:fc247511da6be0cb5d803105fade34017ede93b6</id>
<content type='text'>
commit 932fa0c1496286e39e14e27194c1ee7c2181629f upstream.

In ntfs3_rename(), when IS_DIRSYNC(new_dir) is true, the code syncs
the renamed file inode instead of the target directory new_dir:
    if (IS_DIRSYNC(new_dir))
        ntfs_sync_inode(inode);      /* should be new_dir */

DIRSYNC requires that directory metadata changes are written to disk
synchronously.  Since new_dir was modified (a new directory entry was
added), it is new_dir that must be synced to satisfy the guarantee,
not the renamed file itself.

This bug has existed since the initial ntfs3 implementation and was
carried through the refactoring in commit 78ab59fee07f
("fs/ntfs3: Rework file operations").

Fix by syncing new_dir instead of inode.

Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
Cc: stable@vger.kernel.org
Signed-off-by: Zhan Xusheng &lt;zhanxusheng@xiaomi.com&gt;
Signed-off-by: Konstantin Komarov &lt;almaz.alexandrovich@paragon-software.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>fs/ntfs3: validate Dirty Page Table capacity in log_replay copy_lcns</title>
<updated>2026-07-24T13:51:21+00:00</updated>
<author>
<name>Yunpeng Tian</name>
<email>shionthanatos@gmail.com</email>
</author>
<published>2026-05-04T14:19:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=964c3fae1dfc49dde5468eace940f199cda234e9'/>
<id>urn:sha1:964c3fae1dfc49dde5468eace940f199cda234e9</id>
<content type='text'>
commit 57382ec6ac63b63dce2789e835fded28b698ae79 upstream.

In the analysis pass of $LogFile journal replay, log_replay() copies
LCNs from each action log record into an existing Dirty Page Table
(DPT) entry without bounding the destination index. A crafted NTFS
image with DPT entry lcns_follow=1 and an action log record with
lcns_follow=2 produces a kernel slab out-of-bounds write at mount
time:

  BUG: KASAN: slab-out-of-bounds in log_replay+0x654c/0xdb60
  Write of size 8 at addr ffff8880095e1040 by task mount

Two attacker-controlled fields can drive j+i past the allocated
page_lcns[] array:

  1. dp-&gt;lcns_follow (capacity) can be smaller than lrh-&gt;lcns_follow.
  2. lrh-&gt;target_vcn may be smaller than dp-&gt;vcn, making the u64
     subtraction wrap to a huge size_t.

Validate target VCN delta and per-record LCN count against the
DPT entry capacity, bail via the existing out: cleanup label with
-EINVAL.

This mirrors the bounds-check pattern added in commit b2bc7c44ed17
("fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot")
and commit 0ca0485e4b2e ("fs/ntfs3: validate rec-&gt;used in
journal-replay file record check").

Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
Reported-by: Yunpeng Tian &lt;shionthanatos@gmail.com&gt;
Reported-by: Mingda Zhang &lt;npczmd@qq.com&gt;
Reported-by: Gongming Wang &lt;gmwgg05@gmail.com&gt;
Reported-by: Peiyuan Xu &lt;paulbucket12@gmail.com&gt;
Reported-by: Qinrun Dai &lt;jupmouse@gmail.com&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Yunpeng Tian &lt;shionthanatos@gmail.com&gt;
Signed-off-by: Konstantin Komarov &lt;almaz.alexandrovich@paragon-software.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
</feed>
