mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
libxc/PM: Ensure pxstat buffers are correctly sized
xc_pm_get_pxstat() requires the caller to allocate the pt and trans_pt
buffers but then calls xc_pm_get_max_px() to determine how big they are
(and hence how much Xen will copy into them). This is susceptible to
races if xc_pm_get_max_px() changes so avoid the problem by requiring
the caller to also pass in the size of the buffers.
Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Reviewed-by: Anthony PERARD <anthony.perard@vates.tech>
master commit: de6a05a8a0
master date: 2025-06-11 11:06:45 +0200
This commit is contained in:
1 parent
f830240555
commit
395f34d112
2 files changed
+11
-12
No files matched your search
+10
-12
@@ -45,36 +45,34 @@ int xc_pm_get_max_px(xc_interface *xch, int cpuid, int *max_px)
|
||||
int xc_pm_get_pxstat(xc_interface *xch, int cpuid, struct xc_px_stat *pxpt)
|
||||
{
|
||||
struct xen_sysctl sysctl = {};
|
||||
/* Sizes unknown until xc_pm_get_max_px */
|
||||
DECLARE_NAMED_HYPERCALL_BOUNCE(trans, pxpt->trans_pt, 0, XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
|
||||
DECLARE_NAMED_HYPERCALL_BOUNCE(pt, pxpt->pt, 0, XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
|
||||
DECLARE_NAMED_HYPERCALL_BOUNCE(trans, pxpt->trans_pt,
|
||||
pxpt->total * pxpt->total * sizeof(uint64_t),
|
||||
XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
|
||||
DECLARE_NAMED_HYPERCALL_BOUNCE(pt, pxpt->pt,
|
||||
pxpt->total * sizeof(struct xc_px_val),
|
||||
XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
|
||||
|
||||
int max_px, ret;
|
||||
int ret;
|
||||
|
||||
if ( !pxpt->trans_pt || !pxpt->pt )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if ( (ret = xc_pm_get_max_px(xch, cpuid, &max_px)) != 0)
|
||||
return ret;
|
||||
|
||||
HYPERCALL_BOUNCE_SET_SIZE(trans, max_px * max_px * sizeof(uint64_t));
|
||||
HYPERCALL_BOUNCE_SET_SIZE(pt, max_px * sizeof(struct xc_px_val));
|
||||
|
||||
if ( xc_hypercall_bounce_pre(xch, trans) )
|
||||
return ret;
|
||||
return -1;
|
||||
|
||||
if ( xc_hypercall_bounce_pre(xch, pt) )
|
||||
{
|
||||
xc_hypercall_bounce_post(xch, trans);
|
||||
return ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sysctl.cmd = XEN_SYSCTL_get_pmstat;
|
||||
sysctl.u.get_pmstat.type = PMSTAT_get_pxstat;
|
||||
sysctl.u.get_pmstat.cpuid = cpuid;
|
||||
sysctl.u.get_pmstat.u.getpx.total = max_px;
|
||||
sysctl.u.get_pmstat.u.getpx.total = pxpt->total;
|
||||
set_xen_guest_handle(sysctl.u.get_pmstat.u.getpx.trans_pt, trans);
|
||||
set_xen_guest_handle(sysctl.u.get_pmstat.u.getpx.pt, pt);
|
||||
|
||||
|
||||
@@ -319,6 +319,7 @@ static int get_pxstat_by_cpuid(xc_interface *xc_handle, int cpuid, struct xc_px_
|
||||
if ( !pxstat)
|
||||
return -EINVAL;
|
||||
|
||||
pxstat->total = max_px_num;
|
||||
pxstat->trans_pt = malloc(max_px_num * max_px_num *
|
||||
sizeof(uint64_t));
|
||||
if ( !pxstat->trans_pt )
|
||||
|
||||