From: Jan Beulich Date: Thu, 6 Feb 2014 11:20:20 +0000 (+0100) Subject: domctl: also pause domain for "extended" context updates X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~5627 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=53f808a3880da13d0a0909f446698891a41f6869;p=xen.git domctl: also pause domain for "extended" context updates This is not just for consistency with "base" context updates, but actually needed so that guest side accesses can't race with control domain side updates. This would have been a security issue if XSA-77 hadn't waived them on the affected domctl operation. While looking at the code I also spotted a redundant NULL check in the "base" context update handling code, which is being removed. Signed-off-by: Jan Beulich Acked-by: Keir Fraser Reviewed-by: Andrew Cooper Release-acked-by: George Dunlap --- diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 41cfd7c3cb..432a180865 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -853,6 +853,8 @@ long arch_do_domctl( } else { + if ( d == current->domain ) /* no domain_pause() */ + break; ret = -EINVAL; if ( evc->size < offsetof(typeof(*evc), vmce) ) break; @@ -861,6 +863,7 @@ long arch_do_domctl( if ( !is_canonical_address(evc->sysenter_callback_eip) || !is_canonical_address(evc->syscall32_callback_eip) ) break; + domain_pause(d); fixup_guest_code_selector(d, evc->sysenter_callback_cs); v->arch.pv_vcpu.sysenter_callback_cs = evc->sysenter_callback_cs; @@ -881,6 +884,8 @@ long arch_do_domctl( (evc->syscall32_callback_cs & ~3) || evc->syscall32_callback_eip ) break; + else + domain_pause(d); BUILD_BUG_ON(offsetof(struct xen_domctl_ext_vcpucontext, mcg_cap) != @@ -899,6 +904,8 @@ long arch_do_domctl( } else ret = 0; + + domain_unpause(d); } } break; diff --git a/xen/common/domctl.c b/xen/common/domctl.c index 904d27bb79..f237be4a77 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -334,10 +334,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) unsigned int vcpu = op->u.vcpucontext.vcpu; struct vcpu *v; - ret = -ESRCH; - if ( d == NULL ) - break; - ret = -EINVAL; if ( (d == current->domain) || /* no domain_pause() */ (vcpu >= d->max_vcpus) || ((v = d->vcpu[vcpu]) == NULL) )