summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorOmar Sandoval <osandov@fb.com>2024-09-30 20:55:00 +0200
committerChristian Brauner <brauner@kernel.org>2024-10-01 11:49:57 +0200
commit0d24852bd71ec85ca0016b6d6fc997e6a3381552 (patch)
tree5890cf52ed965d8359bb8c4989f0f90e136a9bab /lib
parentMerge tag 'sched_ext-for-6.12-rc1-fixes-1' of git://git.kernel.org/pub/scm/li... (diff)
downloadlinux-0d24852bd71ec85ca0016b6d6fc997e6a3381552.tar.xz
linux-0d24852bd71ec85ca0016b6d6fc997e6a3381552.zip
iov_iter: fix advancing slot in iter_folioq_get_pages()
iter_folioq_get_pages() decides to advance to the next folioq slot when it has reached the end of the current folio. However, it is checking offset, which is the beginning of the current part, instead of iov_offset, which is adjusted to the end of the current part, so it doesn't advance the slot when it's supposed to. As a result, on the next iteration, we'll use the same folio with an out-of-bounds offset and return an unrelated page. This manifested as various crashes and other failures in 9pfs in drgn's VM testing setup and BPF CI. Fixes: db0aa2e9566f ("mm: Define struct folio_queue and ITER_FOLIOQ to handle a sequence of folios") Link: https://lore.kernel.org/linux-fsdevel/20240923183432.1876750-1-chantr4@gmail.com/ Tested-by: Manu Bretelle <chantr4@gmail.com> Signed-off-by: Omar Sandoval <osandov@fb.com> Link: https://lore.kernel.org/r/cbaf141ba6c0e2e209717d02746584072844841a.1727722269.git.osandov@fb.com Tested-by: Eduard Zingerman <eddyz87@gmail.com> Tested-by: Leon Romanovsky <leon@kernel.org> Tested-by: Joey Gouly <joey.gouly@arm.com> Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/iov_iter.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 97003155bfac..1abb32c0da50 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -1033,7 +1033,7 @@ static ssize_t iter_folioq_get_pages(struct iov_iter *iter,
if (maxpages == 0 || extracted >= maxsize)
break;
- if (offset >= fsize) {
+ if (iov_offset >= fsize) {
iov_offset = 0;
slot++;
if (slot == folioq_nr_slots(folioq) && folioq->next) {