ntfs: fix runlist marker allocation and count

The marker path can append an unmapped element and an ENOENT
terminator after the merge helpers have already computed the resulting
runlist count. In that case, allocating ds + 2 elements leaves no room
for the terminator at ds + 2. The path also increments new_rl_count even
though the merge helper already accounted for the final runlist size,
causing a later merge to start past the terminator.

Allocate space through ds + 2, and derive new_rl_count from the final
terminator index instead of incrementing the count a second time.

A crafted NTFS image can reach this path through a normal read after the
image has been mounted and trigger out-of-bounds kernel heap accesses.

Fixes: 11ccc9107d ("ntfs: update runlist handling and cluster allocator")

Assisted-by: OpenAI Codex:GPT-5
Signed-off-by: pwngets <2605452642@qq.com>
Reviewed-by: Baolin Liu <liubaolin@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
pwngets 2026-09-23 13:41:06 +08:00 committed by Namjae Jeon
parent ca43660672
commit c1bd2f1c22

View File

@ -680,9 +680,8 @@ struct runlist_element *ntfs_runlists_merge(struct runlist *d_runlist,
/* Add an unmapped runlist element. */
if (!slots) {
drl = ntfs_rl_realloc_nofail(drl, ds,
ds + 2);
ds + 3);
slots = 2;
*new_rl_count += 2;
}
ds++;
/* Need to set vcn if it isn't set already. */
@ -698,11 +697,11 @@ struct runlist_element *ntfs_runlists_merge(struct runlist *d_runlist,
ds++;
if (!slots) {
drl = ntfs_rl_realloc_nofail(drl, ds, ds + 1);
*new_rl_count += 1;
}
drl[ds].vcn = marker_vcn;
drl[ds].lcn = LCN_ENOENT;
drl[ds].length = (s64)0;
*new_rl_count = ds + 1;
}
}
}