Skip to content

Commit 8357d75

Browse files
jgross1gregkh
authored andcommitted
xen/9p: use alloc/free_pages_exact()
Commit 5cadd4b upstream. Instead of __get_free_pages() and free_pages() use alloc_pages_exact() and free_pages_exact(). This is in preparation of a change of gnttab_end_foreign_access() which will prohibit use of high-order pages. By using the local variable "order" instead of ring->intf->ring_order in the error path of xen_9pfs_front_alloc_dataring() another bug is fixed, as the error path can be entered before ring->intf->ring_order is being set. By using alloc_pages_exact() the size in bytes is specified for the allocation, which fixes another bug for the case of order < (PAGE_SHIFT - XEN_PAGE_SHIFT). This is part of CVE-2022-23041 / XSA-396. Reported-by: Simon Gaiser <simon@invisiblethingslab.com> Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 17f01b7 commit 8357d75

1 file changed

Lines changed: 6 additions & 8 deletions

File tree

net/9p/trans_xen.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,9 @@ static void xen_9pfs_front_free(struct xen_9pfs_front_priv *priv)
304304
ref = priv->rings[i].intf->ref[j];
305305
gnttab_end_foreign_access(ref, 0, 0);
306306
}
307-
free_pages((unsigned long)priv->rings[i].data.in,
308-
priv->rings[i].intf->ring_order -
309-
(PAGE_SHIFT - XEN_PAGE_SHIFT));
307+
free_pages_exact(priv->rings[i].data.in,
308+
1UL << (priv->rings[i].intf->ring_order +
309+
XEN_PAGE_SHIFT));
310310
}
311311
gnttab_end_foreign_access(priv->rings[i].ref, 0, 0);
312312
free_page((unsigned long)priv->rings[i].intf);
@@ -345,8 +345,8 @@ static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
345345
if (ret < 0)
346346
goto out;
347347
ring->ref = ret;
348-
bytes = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
349-
order - (PAGE_SHIFT - XEN_PAGE_SHIFT));
348+
bytes = alloc_pages_exact(1UL << (order + XEN_PAGE_SHIFT),
349+
GFP_KERNEL | __GFP_ZERO);
350350
if (!bytes) {
351351
ret = -ENOMEM;
352352
goto out;
@@ -377,9 +377,7 @@ static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
377377
if (bytes) {
378378
for (i--; i >= 0; i--)
379379
gnttab_end_foreign_access(ring->intf->ref[i], 0, 0);
380-
free_pages((unsigned long)bytes,
381-
ring->intf->ring_order -
382-
(PAGE_SHIFT - XEN_PAGE_SHIFT));
380+
free_pages_exact(bytes, 1UL << (order + XEN_PAGE_SHIFT));
383381
}
384382
gnttab_end_foreign_access(ring->ref, 0, 0);
385383
free_page((unsigned long)ring->intf);

0 commit comments

Comments
 (0)