xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Paul Durrant <Paul.Durrant@citrix.com>
To: Andrew Cooper <Andrew.Cooper3@citrix.com>,
	"xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>
Cc: Ian Jackson <Ian.Jackson@citrix.com>,
	Daniel De Graaf <dgdegra@tycho.nsa.gov>,
	Jennifer Herbert <jennifer.herbert@citrix.com>,
	Wei Liu <wei.liu2@citrix.com>, Jan Beulich <jbeulich@suse.com>
Subject: Re: [PATCH v4 1/8] public / x86: Introduce __HYPERCALL_dm_op...
Date: Fri, 20 Jan 2017 15:02:53 +0000	[thread overview]
Message-ID: <2beab20fec434dd38ca636aed123c9f4@AMSPEX02CL03.citrite.net> (raw)
In-Reply-To: <8453657b-fecf-6577-8f0a-4392a24191b4@citrix.com>

> -----Original Message-----
> From: Andrew Cooper
> Sent: 20 January 2017 14:35
> To: Paul Durrant <Paul.Durrant@citrix.com>; xen-devel@lists.xenproject.org
> Cc: Ian Jackson <Ian.Jackson@citrix.com>; Jennifer Herbert
> <jennifer.herbert@citrix.com>; Daniel De Graaf <dgdegra@tycho.nsa.gov>;
> Wei Liu <wei.liu2@citrix.com>; Jan Beulich <jbeulich@suse.com>
> Subject: Re: [PATCH v4 1/8] public / x86: Introduce __HYPERCALL_dm_op...
> 
> On 17/01/17 17:29, Paul Durrant wrote:
> > ...as a set of hypercalls to be used by a device model.
> >
> > As stated in the new docs/designs/dm_op.markdown:
> >
> > "The aim of DMOP is to prevent a compromised device model from
> > compromising domains other then the one it is associated with. (And is
> > therefore likely already compromised)."
> 
> "associated with" is a bit ambiguous, as a dm running in dom0 is
> associated with dom0.
> 
> How about "other than the one it is providing emulation for." ?
> 

Yes, that's clearer.

> > +The Design
> > +----------
> > +
> > +The privcmd driver implements a new restriction ioctl, which takes a
> domid
> > +parameter.  After that restriction ioctl is issued, the privcmd driver will
> > +permit only DMOP hypercalls, and only with the specified target domid.
> 
> The plan (iirc) is to implement dmop via a new ioctl() on /dev/xen/privcmd
> 
> At the point that restrict() is called, all unaudited operations on
> /dev/xen/privcmd should cease to function, including regular hypercalls.
> 

That makes sense, but I may not have been in the loop for that bit of planning. I'll certainly add the text though.

> > diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
> > new file mode 100644
> > index 0000000..f00bc2c
> > --- /dev/null
> > +++ b/xen/arch/x86/hvm/dm.c
> > @@ -0,0 +1,149 @@
> > +/*
> > + * Copyright (c) 2016 Citrix Systems Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms and conditions of the GNU General Public License,
> > + * version 2, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope it will be useful, but WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of
> MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
> License for
> > + * more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> along with
> > + * this program; If not, see <http://www.gnu.org/licenses/>.
> > + */
> > +
> > +#include <xen/guest_access.h>
> > +#include <xen/hypercall.h>
> > +#include <xen/sched.h>
> > +
> > +#include <asm/hvm/ioreq.h>
> > +
> > +#include <xsm/xsm.h>
> > +
> > +static bool copy_buf_from_guest(xen_dm_op_buf_t bufs[],
> > +                                unsigned int nr_bufs, void *dst,
> > +                                unsigned int idx, size_t dst_size)
> > +{
> > +    size_t size = min_t(size_t, dst_size, bufs[idx].size);
> > +
> > +    return !copy_from_guest(dst, bufs[idx].h, size);
> > +}
> > +
> > +static bool copy_buf_to_guest(xen_dm_op_buf_t bufs[],
> > +                              unsigned int nr_bufs, unsigned int idx,
> > +                              void *src, size_t src_size)
> > +{
> > +    size_t size = min_t(size_t, bufs[idx].size, src_size);
> > +
> > +    return !copy_to_guest(bufs[idx].h, src, size);
> > +}
> > +
> > +static int dm_op(domid_t domid,
> > +                 unsigned int nr_bufs,
> > +                 xen_dm_op_buf_t bufs[])
> > +{
> > +    struct domain *d;
> > +    struct xen_dm_op op;
> > +    long rc;
> > +
> > +    rc = rcu_lock_remote_domain_by_id(domid, &d);
> > +    if ( rc )
> > +        return rc;
> > +
> > +    if ( !has_hvm_container_domain(d) )
> > +        goto out;
> > +
> > +    rc = xsm_dm_op(XSM_DM_PRIV, d);
> > +    if ( rc )
> > +        goto out;
> > +
> > +    if ( !copy_buf_from_guest(bufs, nr_bufs, &op, 0, sizeof(op)) )
> > +    {
> > +        rc = -EFAULT;
> > +        goto out;
> > +    }
> > +
> > +    switch ( op.op )
> > +    {
> > +    default:
> > +        rc = -EOPNOTSUPP;
> > +        break;
> > +    }
> > +
> > +    if ( !rc &&
> > +         !copy_buf_to_guest(bufs, nr_bufs, 0, &op, sizeof(op)) )
> 
> Do all ops need a copyback?  If they do, this is fine.  If not, it would
> be better to have a copyback boolean which subops set as necessary.

I can restrict copy-back using a boolean set for sub-ops that have 'out' params, or when there needs to be a continuation but I didn't really think it was worth the extra complexity.

> 
> > +        rc = -EFAULT;
> > +
> > + out:
> > +    rcu_unlock_domain(d);
> > +
> > +    return rc;
> > +}
> > +
> > +int compat_dm_op(domid_t domid,
> > +                 unsigned int nr_bufs,
> > +                 COMPAT_HANDLE_PARAM(compat_dm_op_buf_t) bufs)
> > +{
> > +    struct xen_dm_op_buf *nat;
> > +    unsigned int i;
> > +    int rc = -EFAULT;
> > +
> > +    nat = xzalloc_array(struct xen_dm_op_buf, nr_bufs);
> > +    if ( !nat )
> > +        return -ENOMEM;
> > +
> > +    for ( i = 0; i < nr_bufs; i++ )
> > +    {
> > +        struct compat_dm_op_buf cmp;
> > +
> > +        if ( copy_from_compat_offset(&cmp, bufs, i, 1) )
> > +            goto out;
> > +
> > +#define XLAT_dm_op_buf_HNDL_h(_d_, _s_) \
> > +        guest_from_compat_handle((_d_)->h, (_s_)->h)
> > +
> > +        XLAT_dm_op_buf(&nat[i], &cmp);
> > +
> > +#undef XLAT_dm_op_buf_HNDL_h
> > +    }
> > +
> > +    rc = dm_op(domid, nr_bufs, nat);
> > +
> > + out:
> > +    xfree(nat);
> > +
> > +    return rc;
> > +}
> > +
> > +long do_dm_op(domid_t domid,
> > +              unsigned int nr_bufs,
> > +              XEN_GUEST_HANDLE_PARAM(xen_dm_op_buf_t) bufs)
> > +{
> > +    struct xen_dm_op_buf *nat;
> > +    int rc;
> > +
> > +    nat = xzalloc_array(struct xen_dm_op_buf, nr_bufs);
> > +    if ( !nat )
> > +        return -ENOMEM;
> 
> nr_bufs is a guest-passed value at this point, and needs a boundary check.
> 
> The maximum number of bufs on all implemented ops is 2, isn't it?  I'd
> have a define somewhere, audit against the global max, and put the array
> on the stack to avoid the memory allocation.
> 

Yes, I'll define max value and put it on the stack as you suggest.

> Otherwise, LGTM.

Cool. Thanks,

  Paul

> 
> ~Andrew

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

  reply	other threads:[~2017-01-20 15:02 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-17 17:29 [PATCH v4 0/8] New hypercall for device models Paul Durrant
2017-01-17 17:29 ` [PATCH v4 1/8] public / x86: Introduce __HYPERCALL_dm_op Paul Durrant
2017-01-18 19:18   ` Daniel De Graaf
2017-01-19  9:01   ` Paul Durrant
2017-01-20 14:35   ` Andrew Cooper
2017-01-20 15:02     ` Paul Durrant [this message]
2017-01-23  9:15       ` Andrew Cooper
2017-01-23  9:17         ` Paul Durrant
2017-01-20 15:54   ` Wei Liu
2017-01-20 15:59     ` Paul Durrant
2017-01-20 16:03       ` Wei Liu
2017-01-20 16:17   ` Jan Beulich
2017-01-20 16:20     ` Paul Durrant
2017-01-20 16:38       ` Jan Beulich
2017-01-20 16:39         ` Paul Durrant
2017-01-17 17:29 ` [PATCH v4 2/8] dm_op: convert HVMOP_*ioreq_server* Paul Durrant
2017-01-18  9:55   ` Jan Beulich
2017-01-18 10:10     ` Paul Durrant
2017-01-18 19:19   ` Daniel De Graaf
2017-01-20 15:17   ` Andrew Cooper
2017-01-17 17:29 ` [PATCH v4 3/8] dm_op: convert HVMOP_track_dirty_vram Paul Durrant
2017-01-18 19:20   ` Daniel De Graaf
2017-01-20 16:20   ` Jan Beulich
2017-01-20 16:29     ` Paul Durrant
2017-01-20 16:32     ` Paul Durrant
2017-01-20 16:38       ` Jan Beulich
2017-01-20 17:22   ` Andrew Cooper
2017-01-17 17:29 ` [PATCH v4 4/8] dm_op: convert HVMOP_set_pci_intx_level, HVMOP_set_isa_irq_level, and Paul Durrant
2017-01-18 19:20   ` Daniel De Graaf
2017-01-20 17:31   ` [offlist] " Andrew Cooper
2017-01-17 17:29 ` [PATCH v4 5/8] dm_op: convert HVMOP_modified_memory Paul Durrant
2017-01-18 19:20   ` Daniel De Graaf
2017-01-20 16:24   ` Jan Beulich
2017-01-20 18:15   ` Andrew Cooper
2017-01-17 17:29 ` [PATCH v4 6/8] dm_op: convert HVMOP_set_mem_type Paul Durrant
2017-01-18 19:20   ` Daniel De Graaf
2017-01-20 18:28   ` Andrew Cooper
2017-01-23  8:52     ` Paul Durrant
2017-01-17 17:29 ` [PATCH v4 7/8] dm_op: convert HVMOP_inject_trap and HVMOP_inject_msi Paul Durrant
2017-01-18 19:21   ` Daniel De Graaf
2017-01-20 18:33   ` Andrew Cooper
2017-01-23  8:50     ` Paul Durrant
2017-01-17 17:29 ` [PATCH v4 8/8] x86/hvm: serialize trap injecting producer and consumer Paul Durrant

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=2beab20fec434dd38ca636aed123c9f4@AMSPEX02CL03.citrite.net \
    --to=paul.durrant@citrix.com \
    --cc=Andrew.Cooper3@citrix.com \
    --cc=Ian.Jackson@citrix.com \
    --cc=dgdegra@tycho.nsa.gov \
    --cc=jbeulich@suse.com \
    --cc=jennifer.herbert@citrix.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xenproject.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).