mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
vhost-scsi: fix page reference leak in misaligned I/O fallback
iov_iter_get_pages2() returns a byte count that excludes the offset into
the first page, but also returns a reference to that page in pages[].
On the misaligned-I/O fallback, vhost_scsi_revert_map_iov_to_sgl() puts
pages already added to the SG list. The cleanup loop starts at
pages[npages], but accounts for its first page as PAGE_SIZE bytes
rather than PAGE_SIZE - offset. If the remaining data starts at a
non-zero offset, it can finish one page early and leave a page reference
behind.
Use PAGE_SIZE - offset for the first remaining page and clear offset for
later pages, as in the mapping loop. Without this, each affected request
leaks one page reference.
Fixes: bca939d5bc ("vhost-scsi: Dynamically allocate scatterlists")
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261023104035.6686-1-physicalmtea@gmail.com>
This commit is contained in:
parent
bb2e6f1665
commit
058fc59326
|
|
@ -900,11 +900,16 @@ vhost_scsi_map_to_sgl(struct vhost_scsi_cmd *cmd,
|
|||
vhost_scsi_revert_map_iov_to_sgl(iter, *sgl, sg);
|
||||
|
||||
iov_iter_revert(iter, bytes);
|
||||
/*
|
||||
* pages[npages] is the first page not added to the SG list.
|
||||
* The remaining data starts at offset in that page.
|
||||
*/
|
||||
while (bytes) {
|
||||
n = min_t(unsigned int, PAGE_SIZE, bytes);
|
||||
n = min_t(unsigned int, PAGE_SIZE - offset, bytes);
|
||||
|
||||
put_page(pages[npages++]);
|
||||
bytes -= n;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user