[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 2/3] x86/hvm: introduce functions for HVMOP_get/set_param allowance checks
On 05/05/15 11:25, Paul Durrant wrote: > Some parameters can only (validly) be set once. Some should not be set > by a guest for its own domain, and others must not be set since they > require the domain to be paused. Consolidate these checks, along with > the XSM check, in a new hvm_allow_set_param() function for clarity. > > Also, introduce hvm_allow_get_param() for similar reasons. > > NOTE: This patch leaves the guest accessible parameter checks as > black-lists and does not make any changes to which parameters > can be accessed. A subsequent patch will tighten up these > checks by changing from black-lists to white-lists. > > Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> > Cc: Keir Fraser <keir@xxxxxxx> > Cc: Jan Beulich <jbeulich@xxxxxxxx> > Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> > --- > xen/arch/x86/hvm/hvm.c | 153 > ++++++++++++++++++++++++++++-------------------- > 1 file changed, 90 insertions(+), 63 deletions(-) > > diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c > index c246b45..03543dd 100644 > --- a/xen/arch/x86/hvm/hvm.c > +++ b/xen/arch/x86/hvm/hvm.c > @@ -5638,6 +5638,61 @@ static int hvmop_set_evtchn_upcall_vector( > return 0; > } > > +static int hvm_allow_set_param(struct domain *d, > + const struct xen_hvm_param *a) > +{ > + uint64_t value = d->arch.hvm_domain.params[a->index]; > + int rc; > + > + rc = xsm_hvm_param(XSM_TARGET, d, HVMOP_set_param); > + if ( rc ) > + return rc; > + > + switch ( a->index ) > + { > + /* > + * The following parameters must not be set by the guest > + * since the domain may need to be paused. > + */ > + case HVM_PARAM_IDENT_PT: > + case HVM_PARAM_DM_DOMAIN: > + case HVM_PARAM_ACPI_S_STATE: > + /* The following parameters should not be set by the guest. */ > + case HVM_PARAM_VIRIDIAN: > + case HVM_PARAM_MEMORY_EVENT_CR0: > + case HVM_PARAM_MEMORY_EVENT_CR3: > + case HVM_PARAM_MEMORY_EVENT_CR4: > + case HVM_PARAM_MEMORY_EVENT_INT3: > + case HVM_PARAM_MEMORY_EVENT_SINGLE_STEP: > + case HVM_PARAM_MEMORY_EVENT_MSR: > + case HVM_PARAM_IOREQ_SERVER_PFN: > + case HVM_PARAM_NR_IOREQ_SERVER_PAGES: > + if ( d == current->domain ) > + rc = -EPERM; > + break; > + default: > + break; > + } > + > + if ( rc ) > + return rc; > + > + switch ( a->index ) > + { > + /* The following parameters should only be changed once. */ > + case HVM_PARAM_VIRIDIAN: > + case HVM_PARAM_IOREQ_SERVER_PFN: > + case HVM_PARAM_NR_IOREQ_SERVER_PAGES: > + if ( value != 0 && a->value != value ) > + rc = -EEXIST; > + break; > + default: > + break; > + } > + > + return rc; > +} > + > static int hvmop_set_param( > XEN_GUEST_HANDLE_PARAM(xen_hvm_param_t) arg) > { > @@ -5662,7 +5717,7 @@ static int hvmop_set_param( > (is_pvh_domain(d) && (a.index != HVM_PARAM_CALLBACK_IRQ)) ) > goto out; > > - rc = xsm_hvm_param(XSM_TARGET, d, HVMOP_set_param); > + rc = hvm_allow_set_param(d, &a); > if ( rc ) > goto out; > > @@ -5677,31 +5732,11 @@ static int hvmop_set_param( > rc = -EINVAL; > break; > case HVM_PARAM_VIRIDIAN: > - /* This should only ever be set once by the tools and read by the > guest. */ > - rc = -EPERM; > - if ( d == curr_d ) > - break; > - > - if ( a.value != d->arch.hvm_domain.params[a.index] ) > - { > - rc = -EEXIST; > - if ( d->arch.hvm_domain.params[a.index] != 0 ) > - break; > - > + if ( (a.value & ~HVMPV_feature_mask) || > + !(a.value & HVMPV_base_freq) ) > rc = -EINVAL; > - if ( (a.value & ~HVMPV_feature_mask) || > - !(a.value & HVMPV_base_freq) ) > - break; > - } > - > - rc = 0; > break; > case HVM_PARAM_IDENT_PT: > - /* Not reflexive, as we must domain_pause(). */ > - rc = -EPERM; > - if ( d == curr_d ) > - break; > - > rc = -EINVAL; > if ( d->arch.hvm_domain.params[a.index] != 0 ) > break; > @@ -5729,22 +5764,12 @@ static int hvmop_set_param( > domctl_lock_release(); > break; > case HVM_PARAM_DM_DOMAIN: > - /* Not reflexive, as we may need to domain_pause(). */ > - rc = -EPERM; > - if ( d == curr_d ) > - break; > - > if ( a.value == DOMID_SELF ) > a.value = curr_d->domain_id; > > rc = hvm_set_dm_domain(d, a.value); > break; > case HVM_PARAM_ACPI_S_STATE: > - /* Not reflexive, as we must domain_pause(). */ > - rc = -EPERM; > - if ( d == curr_d ) > - break; > - > rc = 0; > if ( a.value == 3 ) > hvm_s3_suspend(d); > @@ -5757,20 +5782,9 @@ static int hvmop_set_param( > case HVM_PARAM_ACPI_IOPORTS_LOCATION: > rc = pmtimer_change_ioport(d, a.value); > break; > - case HVM_PARAM_MEMORY_EVENT_CR0: > - case HVM_PARAM_MEMORY_EVENT_CR3: > - case HVM_PARAM_MEMORY_EVENT_CR4: > - if ( d == curr_d ) > - rc = -EPERM; > - break; > case HVM_PARAM_MEMORY_EVENT_INT3: > case HVM_PARAM_MEMORY_EVENT_SINGLE_STEP: > case HVM_PARAM_MEMORY_EVENT_MSR: > - if ( d == curr_d ) > - { > - rc = -EPERM; > - break; > - } > if ( a.value & HVMPME_onchangeonly ) > rc = -EINVAL; > break; > @@ -5804,22 +5818,12 @@ static int hvmop_set_param( > rc = -EINVAL; > break; > case HVM_PARAM_IOREQ_SERVER_PFN: > - if ( d == curr_d ) > - { > - rc = -EPERM; > - break; > - } > d->arch.hvm_domain.ioreq_gmfn.base = a.value; > break; > case HVM_PARAM_NR_IOREQ_SERVER_PAGES: > { > unsigned int i; > > - if ( d == curr_d ) > - { > - rc = -EPERM; > - break; > - } > if ( a.value == 0 || > a.value > sizeof(d->arch.hvm_domain.ioreq_gmfn.mask) * 8 ) > { > @@ -5859,10 +5863,40 @@ static int hvmop_set_param( > return rc; > } > > +static int hvm_allow_get_param(struct domain *d, > + const struct xen_hvm_param *a) > +{ > + int rc; > + > + rc = xsm_hvm_param(XSM_TARGET, d, HVMOP_get_param); > + if ( rc ) > + return rc; > + > + switch ( a->index ) > + { > + /* > + * The following parameters must not be read by the guest > + * since the domain may need to be paused. > + */ > + case HVM_PARAM_IOREQ_PFN: > + case HVM_PARAM_BUFIOREQ_PFN: > + case HVM_PARAM_BUFIOREQ_EVTCHN: > + /* The following parameters should not be read by the guest. */ > + case HVM_PARAM_IOREQ_SERVER_PFN: > + case HVM_PARAM_NR_IOREQ_SERVER_PAGES: > + if ( d == current->domain ) > + rc = -EPERM; > + break; > + default: > + break; > + } > + > + return rc; > +} > + > static int hvmop_get_param( > XEN_GUEST_HANDLE_PARAM(xen_hvm_param_t) arg) > { > - struct domain *curr_d = current->domain; > struct xen_hvm_param a; > struct domain *d; > int rc; > @@ -5882,7 +5916,7 @@ static int hvmop_get_param( > (is_pvh_domain(d) && (a.index != HVM_PARAM_CALLBACK_IRQ)) ) > goto out; > > - rc = xsm_hvm_param(XSM_TARGET, d, HVMOP_get_param); > + rc = hvm_allow_get_param(d, &a); > if ( rc ) > goto out; > > @@ -5891,13 +5925,6 @@ static int hvmop_get_param( > case HVM_PARAM_ACPI_S_STATE: > a.value = d->arch.hvm_domain.is_s3_suspended ? 3 : 0; > break; > - case HVM_PARAM_IOREQ_SERVER_PFN: > - case HVM_PARAM_NR_IOREQ_SERVER_PAGES: > - if ( d == curr_d ) > - { > - rc = -EPERM; > - goto out; > - } > case HVM_PARAM_IOREQ_PFN: > case HVM_PARAM_BUFIOREQ_PFN: > case HVM_PARAM_BUFIOREQ_EVTCHN: _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |