The RTDS domain-wide XEN_DOMCTL_SCHEDOP_putinfo path only checks for
zero values before applying period and budget to all vCPUs in the
domain.
This is weaker than the per-vCPU XEN_DOMCTL_SCHEDOP_putvcpuinfo path,
which already rejects values below the minimum, above the maximum, and
cases where budget exceeds period.
Use the same validation rules for putinfo as for putvcpuinfo, so
invalid domain-wide updates are rejected with -EINVAL instead of being
applied inconsistently.
Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
---
Changes in v4:
- add R-b
- reorganize p and b checks order for readability
- add const to the struct parameter in rt_validate_params
Changes in v3:
- changed rt_validate_params input to get struct instead of
period and budget
- improved code readability
Changes in v2:
- introduce rt_validate_params helper function to check period and budget
xen/common/sched/rt.c | 37 ++++++++++++++++++++++++-------------
1 file changed, 24 insertions(+), 13 deletions(-)
diff --git a/xen/common/sched/rt.c b/xen/common/sched/rt.c
index 7b1f64a779..b156f61afa 100644
--- a/xen/common/sched/rt.c
+++ b/xen/common/sched/rt.c
@@ -1362,6 +1362,23 @@ out:
unit_schedule_unlock_irq(lock, unit);
}
+static int
+rt_validate_params(const struct xen_domctl_sched_rtds *rtds,
+ s_time_t *period, s_time_t *budget)
+{
+ s_time_t p = MICROSECS(rtds->period);
+ s_time_t b = MICROSECS(rtds->budget);
+
+ if ( p < RTDS_MIN_PERIOD || p > RTDS_MAX_PERIOD ||
+ b < RTDS_MIN_BUDGET || b > p )
+ return -EINVAL;
+
+ *period = p;
+ *budget = b;
+
+ return 0;
+}
+
/*
* set/get each unit info of each domain
*/
@@ -1388,17 +1405,16 @@ rt_dom_cntl(
op->u.rtds.budget = RTDS_DEFAULT_BUDGET / MICROSECS(1);
break;
case XEN_DOMCTL_SCHEDOP_putinfo:
- if ( op->u.rtds.period == 0 || op->u.rtds.budget == 0 )
- {
- rc = -EINVAL;
+ rc = rt_validate_params(&op->u.rtds, &period, &budget);
+ if ( rc )
break;
- }
+
spin_lock_irqsave(&prv->lock, flags);
for_each_sched_unit ( d, unit )
{
svc = rt_unit(unit);
- svc->period = MICROSECS(op->u.rtds.period); /* transfer to nanosec */
- svc->budget = MICROSECS(op->u.rtds.budget);
+ svc->period = period;
+ svc->budget = budget;
}
spin_unlock_irqrestore(&prv->lock, flags);
break;
@@ -1440,14 +1456,9 @@ rt_dom_cntl(
}
else
{
- period = MICROSECS(local_sched.u.rtds.period);
- budget = MICROSECS(local_sched.u.rtds.budget);
- if ( period > RTDS_MAX_PERIOD || budget < RTDS_MIN_BUDGET ||
- budget > period || period < RTDS_MIN_PERIOD )
- {
- rc = -EINVAL;
+ rc = rt_validate_params(&local_sched.u.rtds, &period, &budget);
+ if ( rc )
break;
- }
spin_lock_irqsave(&prv->lock, flags);
svc = rt_unit(d->vcpu[local_sched.vcpuid]->sched_unit);
--
2.43.0
base-commit: a7bf8ff218ca05eb3674fdfd2817f6cff471e96a