From: David Howells <dhowells@redhat.com> mainline inclusion from mainline-v7.2-rc2 commit 55f4bb9373ca4a521f3b0119366db92715a39b81 category: bugfix bugzilla: NA Reference: https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commi... -------------------------------- In iov_iter_extract_xarray_pages(), if no pages are extracted because there's a hole (or something otherwise unextractable) in the xarray, then the calculation of maxsize at the end can go wrong if the starting offset is not zero. Fix this by returning 0 in such a case and freeing the page array if allocated here rather than being passed in. Note that in the near future, ITER_XARRAY should be removed. Fixes: 7d58fe731028 ("iov_iter: Add a function to extract a page list from an iterator") Link: https://sashiko.dev/#/patchset/20260608145432.681865-1-dhowells%40redhat.com Link: https://sashiko.dev/#/patchset/20260616100821.2062304-1-dhowells%40redhat.co... Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260625140640.3116900-6-dhowells@redhat.com Reviewed-by: Christoph Hellwig <hch@lst.de> cc: Paulo Alcantara <pc@manguebit.org> cc: Matthew Wilcox <willy@infradead.org> cc: Christoph Hellwig <hch@infradead.org> cc: Jens Axboe <axboe@kernel.dk> cc: Mike Marshall <hubcap@omnibond.com> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org> Conflicts: lib/iov_iter.c [a little context conflict] Signed-off-by: Chen Jinghuang <chenjinghuang2@huawei.com> --- lib/iov_iter.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 0b8fc9831225..a4cc8d68b409 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -1625,6 +1625,7 @@ static ssize_t iov_iter_extract_xarray_pages(struct iov_iter *i, struct page *page, **p; unsigned int nr = 0, offset; loff_t pos = i->xarray_start + i->iov_offset; + bool will_alloc = !*pages; pgoff_t index = pos >> PAGE_SHIFT; XA_STATE(xas, i->xarray, index); @@ -1653,6 +1654,14 @@ static ssize_t iov_iter_extract_xarray_pages(struct iov_iter *i, } rcu_read_unlock(); + if (!nr) { + if (will_alloc) { + kvfree(*pages); + *pages = NULL; + } + return 0; + } + maxsize = min_t(size_t, nr * PAGE_SIZE - offset, maxsize); iov_iter_advance(i, maxsize); return maxsize; -- 2.34.1