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:
Ross Lagerwall authored and Jan Beulich committed 2025-07-07 11:35:11 +02:00
1 parent f830240555
commit 395f34d112
2 files changed
+11 -12

No files matched your search

+10 -12
View File
@@ -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);
+1
View File
@@ -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 )
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.