From: Andrew Morton <akpm@linux-foundation.org>
To: mm-commits@vger.kernel.org,pchelkin@ispras.ru,hch@lst.de,axboe@kernel.dk,dmantipov@yandex.ru,akpm@linux-foundation.org
Subject: [to-be-updated] lib-free-pagelist-on-error-in-iov_iter_extract_pages.patch removed from -mm tree
Date: Thu, 04 Jun 2026 11:21:45 -0700 [thread overview]
Message-ID: <20260604182146.326E01F00893@smtp.kernel.org> (raw)
The quilt patch titled
Subject: lib: free pagelist on error in iov_iter_extract_pages()
has been removed from the -mm tree. Its filename was
lib-free-pagelist-on-error-in-iov_iter_extract_pages.patch
This patch was dropped because an updated version will be issued
------------------------------------------------------
From: Dmitry Antipov <dmantipov@yandex.ru>
Subject: lib: free pagelist on error in iov_iter_extract_pages()
Date: Fri, 8 May 2026 14:13:29 +0300
Since 'iov_iter_extract_pages()' may allocate new pagelist if the passed
one isn't large enough, the worst-case scenario may be:
...
struct page *stack_pages[SMALL];
struct page **pages = stack_pages;
...
if (iov_iter_extract_pages(i..., &pages, ...) <= 0) {
/* Even in case of error, new pagelist may be allocated */
if (pages != stack_pages)
kvfree(pages); [1]
/* The rest of error handling and return */
}
/* Regular flow */
...
if (pages != stack_pages)
kvfree(pages);
...
return 0;
If you're unlucky so SMALL amount of pages wasn't enough and new pagelist
was allocated, missing [1] causes the memory leak similar to one I've
recently observed and fixed for 6.12 in [2]. So adjust
'iov_iter_extract_pages()' to make such a cleanup itself rather than rely
on caller's handling on error paths, thus making [1] not needed.
[2] https://lore.kernel.org/stable/20260505094529.406783-1-dmantipov@yandex.ru/T/#u
Link: https://lore.kernel.org/20260508111329.329943-1-dmantipov@yandex.ru
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Suggested-by: Fedor Pchelkin <pchelkin@ispras.ru>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
lib/iov_iter.c | 54 ++++++++++++++++++++++++++++-------------------
1 file changed, 33 insertions(+), 21 deletions(-)
--- a/lib/iov_iter.c~lib-free-pagelist-on-error-in-iov_iter_extract_pages
+++ a/lib/iov_iter.c
@@ -1807,7 +1807,8 @@ static ssize_t iov_iter_extract_user_pag
* (*) Use with ITER_DISCARD is not supported as that has no content.
*
* On success, the function sets *@pages to the new pagelist, if allocated, and
- * sets *offset0 to the offset into the first page.
+ * sets *offset0 to the offset into the first page. On error, new pagelist
+ * is freed if was allocated, and *@pages sets back to its original value.
*
* It may also return -ENOMEM and -EFAULT.
*/
@@ -1818,31 +1819,42 @@ ssize_t iov_iter_extract_pages(struct io
iov_iter_extraction_t extraction_flags,
size_t *offset0)
{
+ struct page **oldpages = *pages;
+ int ret;
+
maxsize = min_t(size_t, min_t(size_t, maxsize, i->count), MAX_RW_COUNT);
if (!maxsize)
return 0;
if (likely(user_backed_iter(i)))
- return iov_iter_extract_user_pages(i, pages, maxsize,
- maxpages, extraction_flags,
- offset0);
- if (iov_iter_is_kvec(i))
- return iov_iter_extract_kvec_pages(i, pages, maxsize,
- maxpages, extraction_flags,
- offset0);
- if (iov_iter_is_bvec(i))
- return iov_iter_extract_bvec_pages(i, pages, maxsize,
- maxpages, extraction_flags,
- offset0);
- if (iov_iter_is_folioq(i))
- return iov_iter_extract_folioq_pages(i, pages, maxsize,
- maxpages, extraction_flags,
- offset0);
- if (iov_iter_is_xarray(i))
- return iov_iter_extract_xarray_pages(i, pages, maxsize,
- maxpages, extraction_flags,
- offset0);
- return -EFAULT;
+ ret = iov_iter_extract_user_pages(i, pages, maxsize,
+ maxpages, extraction_flags,
+ offset0);
+ else if (iov_iter_is_kvec(i))
+ ret = iov_iter_extract_kvec_pages(i, pages, maxsize,
+ maxpages, extraction_flags,
+ offset0);
+ else if (iov_iter_is_bvec(i))
+ ret = iov_iter_extract_bvec_pages(i, pages, maxsize,
+ maxpages, extraction_flags,
+ offset0);
+ else if (iov_iter_is_folioq(i))
+ ret = iov_iter_extract_folioq_pages(i, pages, maxsize,
+ maxpages, extraction_flags,
+ offset0);
+ else if (iov_iter_is_xarray(i))
+ ret = iov_iter_extract_xarray_pages(i, pages, maxsize,
+ maxpages, extraction_flags,
+ offset0);
+ else
+ ret = -EFAULT;
+
+ if (unlikely(ret) && *pages && *pages != oldpages) {
+ kvfree(*pages);
+ *pages = oldpages;
+ }
+
+ return ret;
}
EXPORT_SYMBOL_GPL(iov_iter_extract_pages);
_
Patches currently in -mm which might be from dmantipov@yandex.ru are
ocfs2-fix-buffer-head-management-in-ocfs2_read_blocks.patch
reply other threads:[~2026-06-04 18:21 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260604182146.326E01F00893@smtp.kernel.org \
--to=akpm@linux-foundation.org \
--cc=axboe@kernel.dk \
--cc=dmantipov@yandex.ru \
--cc=hch@lst.de \
--cc=mm-commits@vger.kernel.org \
--cc=pchelkin@ispras.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox