6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Yousef Alhouseen [ Upstream commit 2f497d23652ff23da07b08cfb4b4a1c2a87f1892 ] hdr_insert_head() shifts the existing index entries by ins_bytes without checking that the resulting used size fits within hdr->total. A directory index root larger than the newly allocated index buffer can therefore make the memmove write beyond the buffer. Reject insertions whose size would exceed the index header capacity and make both split callers unwind the new node when that happens. Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block") Reported-by: syzbot+45ef5a8d661162757547@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=45ef5a8d661162757547 Cc: stable@vger.kernel.org Signed-off-by: Yousef Alhouseen Signed-off-by: Konstantin Komarov Signed-off-by: Sasha Levin --- fs/ntfs3/index.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c index 03ae5a817c1b4..97cbe176a83e5 100644 --- a/fs/ntfs3/index.c +++ b/fs/ntfs3/index.c @@ -596,6 +596,8 @@ static const struct NTFS_DE *hdr_insert_head(struct INDEX_HDR *hdr, if (!e) return NULL; + if (size_add(used, ins_bytes) > le32_to_cpu(hdr->total)) + return NULL; /* Now we just make room for the inserted entries and jam it in. */ to_move = used - le32_to_cpu(hdr->de_off); @@ -1800,7 +1802,10 @@ static int indx_insert_into_root(struct ntfs_index *indx, struct ntfs_inode *ni, } /* Copy root entries into new buffer. */ - hdr_insert_head(hdr, re, to_move); + if (!hdr_insert_head(hdr, re, to_move)) { + err = -EINVAL; + goto out_put_n; + } /* Update bitmap attribute. */ indx_mark_used(indx, ni, new_vbn >> indx->idx2vbn_bits); @@ -1952,7 +1957,11 @@ indx_insert_into_buffer(struct ntfs_index *indx, struct ntfs_inode *ni, /* Copy all the entries <= sp into the new buffer. */ de_t = hdr_first_de(hdr1); to_copy = PtrOffset(de_t, sp); - hdr_insert_head(hdr2, de_t, to_copy); + if (!hdr_insert_head(hdr2, de_t, to_copy)) { + err = -EINVAL; + put_indx_node(n2); + goto out; + } /* Remove all entries (sp including) from hdr1. */ used = used1 - to_copy - sp_size; -- 2.53.0