All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jan Beulich" <JBeulich@suse.com>
To: Razvan Cojocaru <rcojocaru@bitdefender.com>
Cc: tim@xen.org, kevin.tian@intel.com, wei.liu2@citrix.com,
	ian.campbell@citrix.com, stefano.stabellini@eu.citrix.com,
	jun.nakajima@intel.com, andrew.cooper3@citrix.com,
	ian.jackson@eu.citrix.com, xen-devel@lists.xen.org,
	eddie.dong@intel.com, Aravind.Gopalakrishnan@amd.com,
	suravee.suthikulpanit@amd.com, keir@xen.org,
	boris.ostrovsky@oracle.com
Subject: Re: [PATCH V2 1/3] xen/vm_access: Support for memory-content hiding
Date: Fri, 26 Jun 2015 09:44:17 +0100	[thread overview]
Message-ID: <558D2D01020000780008A06A@mail.emea.novell.com> (raw)
In-Reply-To: <558D0BC3.7060809@bitdefender.com>

>>> On 26.06.15 at 10:22, <rcojocaru@bitdefender.com> wrote:
> On 06/25/2015 06:57 PM, Jan Beulich wrote:
>>>>> On 15.06.15 at 11:03, <rcojocaru@bitdefender.com> 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

  reply	other threads:[~2015-06-26  8:44 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-15  9:03 Vm_event memory introspection helpers Razvan Cojocaru
2015-06-15  9:03 ` [PATCH V2 1/3] xen/vm_access: Support for memory-content hiding Razvan Cojocaru
2015-06-25 15:57   ` Jan Beulich
2015-06-26  8:22     ` Razvan Cojocaru
2015-06-26  8:44       ` Jan Beulich [this message]
2015-06-26  9:49         ` Razvan Cojocaru
2015-06-26  9:59           ` Jan Beulich
2015-06-15  9:03 ` [PATCH V2 2/3] xen/vm_event: Support for guest-requested events Razvan Cojocaru
2015-06-24 14:56   ` Razvan Cojocaru
2015-06-24 15:03     ` Jan Beulich
2015-06-25  7:55       ` Razvan Cojocaru
2015-06-25  8:37         ` Jan Beulich
2015-06-25  9:09           ` Razvan Cojocaru
2015-06-26  7:02   ` Jan Beulich
2015-06-26  7:17     ` Razvan Cojocaru
2015-06-26  8:45       ` Jan Beulich
2015-06-30 14:48       ` Lengyel, Tamas
2015-06-30 15:22         ` Razvan Cojocaru
2015-07-01  8:24         ` Razvan Cojocaru
2015-07-06 10:26         ` Jan Beulich
2015-07-06 13:46           ` Lengyel, Tamas
2015-06-30 14:23     ` Razvan Cojocaru
2015-07-06 10:27       ` Jan Beulich
2015-07-06 14:35         ` Razvan Cojocaru
2015-06-15  9:03 ` [PATCH V2 3/3] xen/vm_event: Deny register writes if refused by vm_event reply Razvan Cojocaru
2015-06-26  8:28   ` Jan Beulich
2015-06-26  9:17     ` Razvan Cojocaru
2015-06-26  9:39       ` Jan Beulich
2015-06-26 10:33         ` Razvan Cojocaru
2015-07-01 15:21     ` Razvan Cojocaru

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=558D2D01020000780008A06A@mail.emea.novell.com \
    --to=jbeulich@suse.com \
    --cc=Aravind.Gopalakrishnan@amd.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=boris.ostrovsky@oracle.com \
    --cc=eddie.dong@intel.com \
    --cc=ian.campbell@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=jun.nakajima@intel.com \
    --cc=keir@xen.org \
    --cc=kevin.tian@intel.com \
    --cc=rcojocaru@bitdefender.com \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=suravee.suthikulpanit@amd.com \
    --cc=tim@xen.org \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.