CVE-2026-46289
Description
Linux kernel vulnerability in scatterlist allows exceeding page boundaries during data extraction, potentially leading to incorrect calculations and memory issues.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Linux kernel vulnerability in scatterlist allows exceeding page boundaries during data extraction, potentially leading to incorrect calculations and memory issues.
Vulnerability
The Linux kernel's extract_kvec_to_sg function in lib/scatterlist.c contains bugs that can lead to incorrect length calculations when extracting data from a kvec to a scatterlist. Specifically, the calculated length for an sglist entry can exceed the number of bytes in a page, and when extracting from a user buffer, the sglist can be used as a scratch buffer, potentially causing overlap with existing entries. These bugs were introduced in kernel v6.3 and moved to lib/scatterlist.c in v6.5. The fix is marked for backports to v6.5+.
Exploitation
An attacker would need to trigger the extract_kvec_to_sg or extract_iter_to_sg functions with specific inputs that cause the length calculation to exceed page boundaries or lead to overlapping memory regions within the scatterlist when used as a scratch buffer. The exact conditions and sequence of operations required to trigger these bugs are not detailed in the available references, but it involves data extraction operations.
Impact
Successful exploitation of this vulnerability could lead to incorrect length calculations, potentially causing data corruption or unexpected behavior in operations involving scatterlists. When used as a scratch buffer, overlapping memory could lead to further memory corruption. The exact impact, such as information disclosure or denial of service, is not explicitly detailed in the provided references.
Mitigation
This vulnerability has been resolved in the Linux kernel. The fix is available in versions v6.5 and later. Specific patch series "Fix bugs in extract_iter_to_sg()", v3, addresses these issues. No workarounds are mentioned, and the vulnerability is not listed as being part of the KEV catalog. The provided reference [1] is a placeholder page and does not contain technical details about the vulnerability or its mitigation.
AI Insight generated on Jun 8, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
10e5e22fc99634lib/scatterlist: fix length calculations in extract_kvec_to_sg
1 file changed · +3 −3
lib/scatterlist.c+3 −3 modifieddiff --git a/lib/scatterlist.c b/lib/scatterlist.c index 473b2646f71c6..89acf52fede5e 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -1242,7 +1242,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--; @@ -1251,6 +1251,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; @@ -1404,7 +1405,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)) { -- cgit 1.3-korg
07b7d66e65d9lib/scatterlist: fix length calculations in extract_kvec_to_sg
1 file changed · +3 −3
lib/scatterlist.c+3 −3 modifieddiff --git a/lib/scatterlist.c b/lib/scatterlist.c index d773720d11bf2..befdc4b9c11d3 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)) { -- cgit 1.3-korg
9d38756d0a93lib/scatterlist: fix length calculations in extract_kvec_to_sg
1 file changed · +3 −3
lib/scatterlist.c+3 −3 modifieddiff --git a/lib/scatterlist.c b/lib/scatterlist.c index d773720d11bf2..befdc4b9c11d3 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)) { -- cgit 1.3-korg
3f17500e86d7lib/scatterlist: fix length calculations in extract_kvec_to_sg
1 file changed · +3 −3
lib/scatterlist.c+3 −3 modifieddiff --git a/lib/scatterlist.c b/lib/scatterlist.c index 7bc2220fea805..3b87404cdde5f 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -1241,7 +1241,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--; @@ -1250,6 +1250,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; @@ -1342,7 +1343,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)) { -- cgit 1.3-korg
8fbba6829057lib/scatterlist: fix length calculations in extract_kvec_to_sg
1 file changed · +3 −3
lib/scatterlist.c+3 −3 modifieddiff --git a/lib/scatterlist.c b/lib/scatterlist.c index 4af1c8b0775a7..ca9f1c14b7b0d 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -1223,7 +1223,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--; @@ -1232,6 +1232,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; @@ -1385,7 +1386,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)) { -- cgit 1.3-korg
07b7d66e65d9lib/scatterlist: fix length calculations in extract_kvec_to_sg
1 file changed · +3 −3
lib/scatterlist.c+3 −3 modifieddiff --git a/lib/scatterlist.c b/lib/scatterlist.c index d773720d11bf2..befdc4b9c11d3 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)) { -- cgit 1.3-korg
8fbba6829057lib/scatterlist: fix length calculations in extract_kvec_to_sg
1 file changed · +3 −3
lib/scatterlist.c+3 −3 modifieddiff --git a/lib/scatterlist.c b/lib/scatterlist.c index 4af1c8b0775a7..ca9f1c14b7b0d 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -1223,7 +1223,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--; @@ -1232,6 +1232,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; @@ -1385,7 +1386,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)) { -- cgit 1.3-korg
e5e22fc99634lib/scatterlist: fix length calculations in extract_kvec_to_sg
1 file changed · +3 −3
lib/scatterlist.c+3 −3 modifieddiff --git a/lib/scatterlist.c b/lib/scatterlist.c index 473b2646f71c6..89acf52fede5e 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -1242,7 +1242,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--; @@ -1251,6 +1251,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; @@ -1404,7 +1405,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)) { -- cgit 1.3-korg
3f17500e86d7lib/scatterlist: fix length calculations in extract_kvec_to_sg
1 file changed · +3 −3
lib/scatterlist.c+3 −3 modifieddiff --git a/lib/scatterlist.c b/lib/scatterlist.c index 7bc2220fea805..3b87404cdde5f 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -1241,7 +1241,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--; @@ -1250,6 +1250,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; @@ -1342,7 +1343,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)) { -- cgit 1.3-korg
9d38756d0a93lib/scatterlist: fix length calculations in extract_kvec_to_sg
1 file changed · +3 −3
lib/scatterlist.c+3 −3 modifieddiff --git a/lib/scatterlist.c b/lib/scatterlist.c index d773720d11bf2..befdc4b9c11d3 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)) { -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Incorrect length calculations in scatterlist extraction functions can lead to buffer overflows or memory corruption."
Attack vector
An attacker could trigger this vulnerability by providing crafted input that causes the `extract_kvec_to_sg` or `extract_iter_to_sg` functions to miscalculate lengths. This could occur when extracting data from a kvec or user buffer into a scatterlist, potentially leading to operations that exceed allocated memory boundaries.
Affected code
The vulnerability resides in the `extract_kvec_to_sg` and `extract_iter_to_sg` functions within `lib/scatterlist.c`. The patches modify these functions to correct how lengths are calculated and applied when populating scatterlist entries from kvec or user buffers.
What the fix does
The patch series corrects length calculations within the `extract_kvec_to_sg` function. Specifically, it ensures that the length for an sglist entry does not exceed the page size when extracting from a kvec. It also adjusts the copied length if the loop terminates early due to running out of sglist entries, and adds a check to return immediately if no sglist entries are available. These changes prevent the incorrect length calculations that could lead to out-of-bounds memory access.
Generated on Jun 8, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/07b7d66e65d9cfe6b9c2c34aa22cfcaac37a5c45nvd
- git.kernel.org/stable/c/3f17500e86d730c76db638bb3ae52f9b5e496c76nvd
- git.kernel.org/stable/c/8fbba6829057979149d1b37d65690c037f3ddf4dnvd
- git.kernel.org/stable/c/9d38756d0a93b66163554219fa9c3365f40c4035nvd
- git.kernel.org/stable/c/e5e22fc9963469e678c4f4bb38d26adcec107f1envd
News mentions
1- Linux Kernel: 25 Vulnerabilities Disclosed in Single Batch on June 8, 2026Vypr Intelligence · Jun 8, 2026