[PATCH v2 2/3] lib: Fix length calculations in extract_kvec_to_sg

From: Christian A. Ehrhardt

Date: Tue Mar 24 2026 - 16:38:41 EST


When extracting from a kvec to a scatterlist, do not
cross page boundaries. The required length is already
calculated but not used as intended.

Adjust the copied length if the loop runs out auf
sglist entries.

While there return immediately from extract_iter_to_sg
if there are no sglist entries at all.

The changes to the kunit_iov_iter.c in the next commit
demonstrate that the patch is necessary.

Cc: David Howells <dhowells@xxxxxxxxxx>
Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx # v6.5+
Fixes: 018584697533 ("netfs: Add a function to extract an iterator into a scatterlist")
Signed-off-by: Christian A. Ehrhardt <lk@xxxxxxx>
---
lib/scatterlist.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index d773720d11bf..befdc4b9c11d 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -1247,7 +1247,7 @@ static ssize_t extract_kvec_to_sg(struct iov_iter *iter,
else
page = virt_to_page((void *)kaddr);

- sg_set_page(sg, page, len, off);
+ sg_set_page(sg, page, seg, off);
sgtable->nents++;
sg++;
sg_max--;
@@ -1256,6 +1256,7 @@ static ssize_t extract_kvec_to_sg(struct iov_iter *iter,
kaddr += PAGE_SIZE;
off = 0;
} while (len > 0 && sg_max > 0);
+ ret -= len;

if (maxsize <= 0 || sg_max == 0)
break;
@@ -1409,7 +1410,7 @@ ssize_t extract_iter_to_sg(struct iov_iter *iter, size_t maxsize,
struct sg_table *sgtable, unsigned int sg_max,
iov_iter_extraction_t extraction_flags)
{
- if (maxsize == 0)
+ if (maxsize == 0 || sg_max == 0)
return 0;

switch (iov_iter_type(iter)) {
--
2.43.0