xen-blkback: fix leak of grant maps on ring setup failure
Multi page rings are mapped using a single hypercall that gets passed an array of grants to map. One of the grants in the array failing to map would lead to the failure of the whole ring setup operation, but there was no cleanup of the rest of the grant maps in the array that could have likely been created as a result of the hypercall. Add proper cleanup on the failure path during ring setup to unmap any grants that could have been created. This is part of XSA-361. Sponsored by: Citrix Systems R&D
This commit is contained in:
parent
aa8ae5fe17
commit
808d4aad10
@ -2893,10 +2893,31 @@ xbb_connect_ring(struct xbb_softc *xbb)
|
|||||||
ring_idx < xbb->ring_config.ring_pages;
|
ring_idx < xbb->ring_config.ring_pages;
|
||||||
ring_idx++, gnt++) {
|
ring_idx++, gnt++) {
|
||||||
if (gnt->status != 0) {
|
if (gnt->status != 0) {
|
||||||
|
struct gnttab_unmap_grant_ref unmap[XBB_MAX_RING_PAGES];
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
xbb->ring_config.va = 0;
|
xbb->ring_config.va = 0;
|
||||||
xenbus_dev_fatal(xbb->dev, EACCES,
|
xenbus_dev_fatal(xbb->dev, EACCES,
|
||||||
"Ring shared page mapping failed. "
|
"Ring shared page mapping failed. "
|
||||||
"Status %d.", gnt->status);
|
"Status %d.", gnt->status);
|
||||||
|
|
||||||
|
/* Unmap everything to avoid leaking grant table maps */
|
||||||
|
for (i = 0, j = 0; i < xbb->ring_config.ring_pages;
|
||||||
|
i++) {
|
||||||
|
if (gnts[i].status != GNTST_okay)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
unmap[j].host_addr = gnts[i].host_addr;
|
||||||
|
unmap[j].dev_bus_addr = gnts[i].dev_bus_addr;
|
||||||
|
unmap[j++].handle = gnts[i].handle;
|
||||||
|
}
|
||||||
|
if (j != 0) {
|
||||||
|
error = HYPERVISOR_grant_table_op(
|
||||||
|
GNTTABOP_unmap_grant_ref, unmap, j);
|
||||||
|
if (error != 0)
|
||||||
|
panic("Unable to unmap grants (%d)",
|
||||||
|
error);
|
||||||
|
}
|
||||||
return (EACCES);
|
return (EACCES);
|
||||||
}
|
}
|
||||||
xbb->ring_config.handle[ring_idx] = gnt->handle;
|
xbb->ring_config.handle[ring_idx] = gnt->handle;
|
||||||
|
Loading…
Reference in New Issue
Block a user