summaryrefslogtreecommitdiff
path: root/fs/ntfs3/run.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:21:27 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:21:27 +0200
commit8f9aa2c90530ab92301a82231ae44f3722becd93 (patch)
treefb282e955b0a880b07131a135257fe3ec764e928 /fs/ntfs3/run.c
parent93467b31bec6da512b51544e5e4584f2745e995e (diff)
parent155b42bec9cbb6b8cdc47dd9bd09503a81fbe493 (diff)
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/ntfs3/run.c')
-rw-r--r--fs/ntfs3/run.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
index 1ce7d92fb274..ad7db67514ef 100644
--- a/fs/ntfs3/run.c
+++ b/fs/ntfs3/run.c
@@ -1205,18 +1205,23 @@ int run_unpack_ex(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
* Return the highest vcn from a mapping pairs array
* it used while replaying log file.
*/
-int run_get_highest_vcn(CLST vcn, const u8 *run_buf, u64 *highest_vcn)
+int run_get_highest_vcn(CLST vcn, const u8 *run_buf, size_t run_buf_size,
+ u64 *highest_vcn)
{
+ const u8 *run_last = run_buf + run_buf_size;
u64 vcn64 = vcn;
u8 size_size;
- while ((size_size = *run_buf & 0xF)) {
+ while (run_buf < run_last && (size_size = *run_buf & 0xF)) {
u8 offset_size = *run_buf++ >> 4;
u64 len;
if (size_size > 8 || offset_size > 8)
return -EINVAL;
+ if (run_buf + size_size + offset_size > run_last)
+ return -EINVAL;
+
len = run_unpack_s64(run_buf, size_size, 0);
if (!len)
return -EINVAL;
@@ -1292,9 +1297,12 @@ bool run_remove_range(struct runs_tree *run, CLST vcn, CLST len, CLST *done)
if (r_end > end) {
/* Remove a middle part, split. */
+ CLST tail_lcn = r->lcn == SPARSE_LCN ?
+ SPARSE_LCN : (r->lcn + (end - r->vcn));
+
*done += len;
r->len = d;
- return run_add_entry(run, end, r->lcn, r_end - end,
+ return run_add_entry(run, end, tail_lcn, r_end - end,
false);
}
/* Remove tail of run .*/