[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH V2 1/3] xen/vm_access: Support for memory-content hiding



>>> On 26.06.15 at 10:22, <rcojocaru@xxxxxxxxxxxxxxx> wrote:
> On 06/25/2015 06:57 PM, Jan Beulich wrote:
>>>>> On 15.06.15 at 11:03, <rcojocaru@xxxxxxxxxxxxxxx> wrote:
>>> --- a/xen/arch/x86/hvm/emulate.c
>>> +++ b/xen/arch/x86/hvm/emulate.c
>>> @@ -578,6 +578,28 @@ static int hvmemul_read(
>>>          container_of(ctxt, struct hvm_emulate_ctxt, ctxt));
>>>  }
>>>  
>>> +static int hvmemul_read_set_context(
>>> +    enum x86_segment seg,
>>> +    unsigned long offset,
>>> +    void *p_data,
>>> +    unsigned int bytes,
>>> +    struct x86_emulate_ctxt *ctxt)
>>> +{
>>> +    struct vcpu *curr = current;
>>> +    unsigned int len;
>>> +
>>> +    if ( !curr->arch.vm_event.emul_read_data )
>>> +        return X86EMUL_UNHANDLEABLE;
>>> +
>>> +    len = min_t(unsigned int,
>>> +        bytes, curr->arch.vm_event.emul_read_data->size);
>>> +
>>> +    if ( len )
>>> +        memcpy(p_data, curr->arch.vm_event.emul_read_data->data, len);
>> 
>> And the rest of the destination simply remains unmodified /
>> uninitialized?
> 
> It does, yes. Should I memset() it to 0 or something else before the
> memcpy()?

That really depends on your intentions. It just seems (together
with the other cases) inconsistently handled at present. I see
you having three options:
- return actual memory contents for parts of the writes outside
  the overridden range,
- return zero (or another preset value) for such parts,
- fail such operations.
What you shouldn't do is leave data potentially uninitialized (or
else you'd need to make sure that this doesn't result in leaking
hypervisor stack contents anywhere).

>>> @@ -891,14 +934,37 @@ static int hvmemul_rep_outs(
>>>                            !!(ctxt->regs->eflags & X86_EFLAGS_DF), NULL);
>>>  }
>>>  
>>> -static int hvmemul_rep_movs(
>>> +static int hvmemul_rep_outs_set_context(
>>> +    enum x86_segment src_seg,
>>> +    unsigned long src_offset,
>>> +    uint16_t dst_port,
>>> +    unsigned int bytes_per_rep,
>>> +    unsigned long *reps,
>>> +    struct x86_emulate_ctxt *ctxt)
>>> +{
>>> +    struct vcpu *curr = current;
>>> +    unsigned int safe_bytes;
>>> +
>>> +    if ( !curr->arch.vm_event.emul_read_data )
>>> +        return X86EMUL_UNHANDLEABLE;
>>> +
>>> +    safe_bytes = min_t(unsigned int, bytes_per_rep,
>>> +        curr->arch.vm_event.emul_read_data->size);
>>> +
>>> +    return hvmemul_do_pio(dst_port, reps, safe_bytes, 0, IOREQ_WRITE,
>>> +                          !!(ctxt->regs->eflags & X86_EFLAGS_DF),
>>> +                          curr->arch.vm_event.emul_read_data->data);
>> 
>> This isn't consistent with e.g. rep_movs below - you shouldn't
>> reduce the width of the operation.
> 
> I agree, but to be honest I wasn't sure of how to better go about this,
> it seem a bit more involved that the rest of the cases. I could perhaps
> allocate a bytes_per_rep-sized buffer, memset() it to zero and then copy
> safe_bytes from curr->arch.vm_event.emul_read_data->data to the
> beginning of it?

See above - you first need to define the model you want to follow,
and then you need to handle this uniformly everywhere.

>> Also - did I overlook where *reps gets forced to 1? If it's being
>> done elsewhere, perhaps worth an ASSERT()?
> 
> *reps got forced to 1 in hvmemul_rep_stos_set_context() in V1, I took
> that out as per your comments, please see:
> 
> http://lists.xen.org/archives/html/xen-devel/2015-05/msg01054.html 

That's fine, but then you can't simply ignore it in the safe_bytes
calculation.

>>> @@ -981,7 +1047,19 @@ static int hvmemul_rep_movs(
>>>       */
>>>      rc = hvm_copy_from_guest_phys(buf, sgpa, bytes);
>>>      if ( rc == HVMCOPY_okay )
>>> +    {
>>> +        struct vcpu *curr = current;
>>> +
>>> +        if ( unlikely(set_context) && curr->arch.vm_event.emul_read_data )
>>> +        {
>>> +            unsigned long safe_bytes = min_t(unsigned long, bytes,
>>> +                curr->arch.vm_event.emul_read_data->size);
>> 
>> The variable doesn't need to be unsigned long.
> 
> bytes is unsigned long in the function above:
> 
> unsigned long saddr, daddr, bytes;
> 
> I think that's the only place where that is the case, but I had assumed
> that whoever wrote the code knew better and followed suit. I'm happy to
> change both places though.

No, that's not the point. The point is that the result of
min(<unsigned int>, <unsigned long>) always fits in
unsigned int.

>>> @@ -1000,13 +1078,40 @@ static int hvmemul_rep_movs(
>>>      return X86EMUL_OKAY;
>>>  }
>>>  
>>> -static int hvmemul_rep_stos(
>>> +static int hvmemul_rep_movs(
>>> +   enum x86_segment src_seg,
>>> +   unsigned long src_offset,
>>> +   enum x86_segment dst_seg,
>>> +   unsigned long dst_offset,
>>> +   unsigned int bytes_per_rep,
>>> +   unsigned long *reps,
>>> +   struct x86_emulate_ctxt *ctxt)
>>> +{
>>> +    return _hvmemul_rep_movs(src_seg, src_offset, dst_seg, dst_offset,
>>> +                             bytes_per_rep, reps, ctxt, 0);
>>> +}
>>> +
>>> +static int hvmemul_rep_movs_set_context(
>>> +   enum x86_segment src_seg,
>>> +   unsigned long src_offset,
>>> +   enum x86_segment dst_seg,
>>> +   unsigned long dst_offset,
>>> +   unsigned int bytes_per_rep,
>>> +   unsigned long *reps,
>>> +   struct x86_emulate_ctxt *ctxt)
>>> +{
>>> +    return _hvmemul_rep_movs(src_seg, src_offset, dst_seg, dst_offset,
>>> +                             bytes_per_rep, reps, ctxt, 1);
>>> +}
>> 
>> Perhaps putting a flag hvmemul_ctxt would be better?
> 
> Sorry, I don't understand the comment. Can you, please, clarify?

All these wrappers irritate me - a flag in hvmemul_ctxt would - afaict -
eliminate the need for all of them.

> In addition to all the comments, Tamas has kindly pointed out that the
> correct name is mem_access, not vm_event (in the patch title), I'll be
> fixing that too in V3. Sorry for the typo.

Sure - I simply try to not repeat comments others have made.

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.