7.3-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 689712d3463d4..37e3e16b1f841 100644 --- a/fs/ntfs3/index.c +++ b/fs/ntfs3/index.c @@ -594,6 +594,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); @@ -1801,7 +1803,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); @@ -1955,7 +1960,11 @@ static int indx_insert_into_buffer(struct ntfs_index *indx, /* 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