[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 2/6] x86/domctl: Fix TOCTOU race with the use of XEN_DOMCTL_getvcpuextstate
>>> On 12.09.16 at 15:09, <andrew.cooper3@xxxxxxxxxx> wrote: > On 12/09/16 13:33, Jan Beulich wrote: >>>>> On 12.09.16 at 14:02, <andrew.cooper3@xxxxxxxxxx> wrote: >>> On 12/09/16 12:17, Jan Beulich wrote: >>>>>>> On 12.09.16 at 11:51, <andrew.cooper3@xxxxxxxxxx> wrote: >>>>> A toolstack must call XEN_DOMCTL_getvcpuextstate twice; first to find the >>> size >>>>> of the buffer to use, and a second time to get the actual content. >>>>> >>>>> The reported size was based on v->arch.xcr0_accum, but a guest which >>>>> extends >>>>> its xcr0_accum between the two hypercalls will cause the toolstack to >>>>> fail >>> the >>>>> evc->size != size check, as the provided buffer is now too small. This >>>>> causes >>>>> a hard error during the final phase of migration. >>>>> >>>>> Instead, return return a size based on xfeature_mask, which is the maximum >>>>> size Xen will ever permit. The hypercall must now tolerate a >>>>> toolstack-provided buffer which is overly large (for the case where a >>>>> guest >>>>> isn't using all available xsave states), and should write back how much >>>>> data >>>>> was actually written into the buffer. >>>> To be honest, I'm of two minds here. Part of me thinks this is an >>>> okay change. However, in particular ... >>>> >>>>> --- a/xen/arch/x86/domctl.c >>>>> +++ b/xen/arch/x86/domctl.c >>>>> @@ -1054,19 +1054,25 @@ long arch_do_domctl( >>>>> unsigned int size; >>>>> >>>>> ret = 0; >>>>> - vcpu_pause(v); >>>>> >>>>> - size = PV_XSAVE_SIZE(v->arch.xcr0_accum); >>>>> if ( (!evc->size && !evc->xfeature_mask) || >>>>> guest_handle_is_null(evc->buffer) ) >>>>> { >>>>> + /* >>>>> + * A query for the size of buffer to use. Must return >>>>> the >>>>> + * maximum size we ever might hand back to userspace, >>> bearing >>>>> + * in mind that the vcpu might increase its xcr0_accum >>> between >>>>> + * this query for size, and the following query for data. >>>>> + */ >>>>> evc->xfeature_mask = xfeature_mask; >>>>> - evc->size = size; >>>>> - vcpu_unpause(v); >>>>> + evc->size = PV_XSAVE_SIZE(xfeature_mask); >>>>> goto vcpuextstate_out; >>>>> } >>>>> >>>>> - if ( evc->size != size || evc->xfeature_mask != >>>>> xfeature_mask ) >>>>> + vcpu_pause(v); >>>>> + size = PV_XSAVE_SIZE(v->arch.xcr0_accum); >>>>> + >>>>> + if ( evc->size < size || evc->xfeature_mask != xfeature_mask >>>>> ) >>>> ... the relaxation from != to < looks somewhat fragile to me, going >>>> forward. >>> What is fragile about it? It is a very common pattern in general, and >>> we use it elsewhere. >> If we get handed too large a buffer, what meaning do you want to >> assign to the extra bytes? Them being meaningless is just one >> possible interpretation. > > I am confused, and I think you are too. There is no meaning to the > bytes; this is getvcpuextstate, not setvcpuextstate. Oh, indeed. I'm sorry. Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |