x86/pmstat: Check size of PMSTAT_get_pxstat buffers

Check that the total number of states passed in and hence the size of
buffers is sufficient to avoid writing more than the caller has
allocated.

The interface is not explicit about whether getpx.total is expected to
be set by the caller in this case but since it is always set in
libxenctrl it seems reasonable to check it and make it explicit.

Fixes: c06a7db0c5 ("X86 and IA64: Update cpufreq statistic logic for supporting both x86 and ia64")
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>

x86/pmstat: correct PMSTAT_get_pxstat buffer size checking

min(pmpt->perf.state_count, op->u.getpx.total) == op->u.getpx.total can
be expressed differently as pmpt->perf.state_count >= op->u.getpx.total.
Copying when the two are equal is fine; (partial) copying when the state
count is larger than the number of array elements that a buffer was
allocated to hold is what - as per the comment - we mean to avoid. Drop
the use of min() again, but retain its effect for the subsequent copying
from pxpt->u.pt.

Fixes: aa70996a68 ("x86/pmstat: Check size of PMSTAT_get_pxstat buffers")
Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Ross Lagerwall <ross.lagerwall@citrix.com>
master commit: aa70996a68
master date: 2025-06-11 11:05:42 +0200
master commit: fb16c7411d
master date: 2025-06-18 09:25:09 +0200
This commit is contained in:
Ross Lagerwall authored and Jan Beulich committed 2025-06-26 08:37:15 +02:00
1 parent 0cd774e8c2
commit 110bc6ef1a
2 files changed
+20 -3

No files matched your search

+7 -1
View File
@@ -103,8 +103,14 @@ int do_get_pm_info(struct xen_sysctl_get_pmstat *op)
cpufreq_residency_update(op->cpuid, pxpt->u.cur);
/*
* Avoid partial copying of 2-D array, whereas partial copying of a
* simple vector (further down) is deemed okay.
*/
ct = pmpt->perf.state_count;
if ( copy_to_guest(op->u.getpx.trans_pt, pxpt->u.trans_pt, ct*ct) )
if ( ct > op->u.getpx.total )
ct = op->u.getpx.total;
else if ( copy_to_guest(op->u.getpx.trans_pt, pxpt->u.trans_pt, ct * ct) )
{
spin_unlock(cpufreq_statistic_lock);
ret = -EFAULT;
+13 -2
View File
@@ -215,11 +215,22 @@ typedef struct pm_px_val pm_px_val_t;
DEFINE_XEN_GUEST_HANDLE(pm_px_val_t);
struct pm_px_stat {
uint8_t total; /* total Px states */
/*
* IN: Number of elements in pt, number of rows/columns in trans_pt
* (PMSTAT_get_pxstat)
* OUT: total Px states (PMSTAT_get_max_px, PMSTAT_get_pxstat)
*/
uint8_t total;
uint8_t usable; /* usable Px states */
uint8_t last; /* last Px state */
uint8_t cur; /* current Px state */
XEN_GUEST_HANDLE_64(uint64) trans_pt; /* Px transition table */
/*
* OUT: Px transition table. This should have total * total elements.
* As it is a 2-D array, this will not be copied if input total is
* less than output total. (PMSTAT_get_pxstat)
*/
XEN_GUEST_HANDLE_64(uint64) trans_pt;
/* OUT: This should have total elements (PMSTAT_get_pxstat) */
XEN_GUEST_HANDLE_64(pm_px_val_t) 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.