Re: [PATCH] ceph: fix page vector leak on encrypted netfs read EIO path
Tal Zussman <[email protected]>
| Newsgroups | org.kernel.vger.stable,org.kernel.vger.ceph-devel |
|---|---|
| Message-ID | <[email protected]> |
On 8/25/26 12:29 PM, Alex Markuze wrote:
> ceph_netfs_issue_read() pins pages with iov_iter_get_pages_alloc2() for
> encrypted inodes and attaches them with own_pages=false. If
> ceph_inc_osd_stopping_blocker() then fails, the request is dropped
> without calling finish_netfs_read(), so the page array and the
> references taken on those pages leak: ceph_osd_data_release() only
> frees pages when own_pages is true, and __free_pages() would be the
> wrong destructor for GUP-pinned pages.
>
> Release the vector with put_page() and kvfree() on that error path,
> matching finish_netfs_read(). Unencrypted ITER reads are unaffected.
>
> Fixes: 1464de9f813e ("ceph: wait for OSD requests' callbacks to finish when unmounting")
> Cc: [email protected]
> Signed-off-by: Alex Markuze <[email protected]>
Reviewed-by: Tal Zussman <[email protected]>
> ---
> fs/ceph/addr.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
> index c05bdf5d7273..8b009e354d30 100644
> --- a/fs/ceph/addr.c
> +++ b/fs/ceph/addr.c
> @@ -442,6 +442,17 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq)
> osd_req_op_extent_osd_iter(req, 0, &subreq->io_iter);
> }
> if (!ceph_inc_osd_stopping_blocker(fsc->mdsc)) {
> + struct ceph_osd_data *osd_data =
> + osd_req_op_extent_osd_data(req, 0);
> +
> + if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGES) {
> + int num_pages = calc_pages_for(osd_data->alignment,
> + osd_data->length);
> +
> + for (int i = 0; i < num_pages; i++)
> + put_page(osd_data->pages[i]);
> + kvfree(osd_data->pages);
> + }
> err = -EIO;
> goto out;
> }
> --
> 2.34.1
>