All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86/dmop: Fix compat_dm_op() ABI
@ 2017-01-31 19:59 Andrew Cooper
  2017-02-01 10:09 ` Paul Durrant
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Andrew Cooper @ 2017-01-31 19:59 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Paul Durrant, Ian Jackson, Wei Liu, Jan Beulich

The parameter to compat_dm_op() is a pointer to an array of
compat_dm_op_buf_t's in guest RAM.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Paul Durrant <paul.durrant@citrix.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>

What is the pupose of COMPAT_HANDLE_PARAM()? It is a packed structure of one
and a half pointers, so isn't safe at all for use in the hypercall function
APIs (depsite its naming making it look deceptively like it is the correct
thing to use).

On a more serious note, why do we have all this macro infrastrucutre in the
first place?  Having spent rather longer debugging this than I to admit
(almost mainly from the userspace side) I have concluded that it is actively
dangerous to use; all it does is hide what is going on.

What does it actually give us that the Linux route of a real C pointers and a
__user attribute doesn't, other than obfuscating the code on the hypercall
boundary?
---
 xen/arch/x86/hvm/dm.c       | 4 ++--
 xen/include/xen/hypercall.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
index 6a722a5..2122c45 100644
--- a/xen/arch/x86/hvm/dm.c
+++ b/xen/arch/x86/hvm/dm.c
@@ -525,7 +525,7 @@ CHECK_dm_op_inject_msi;
 
 int compat_dm_op(domid_t domid,
                  unsigned int nr_bufs,
-                 COMPAT_HANDLE_PARAM(compat_dm_op_buf_t) bufs)
+                 XEN_GUEST_HANDLE_PARAM(void) bufs)
 {
     struct xen_dm_op_buf nat[MAX_NR_BUFS];
     unsigned int i;
@@ -538,7 +538,7 @@ int compat_dm_op(domid_t domid,
     {
         struct compat_dm_op_buf cmp;
 
-        if ( copy_from_compat_offset(&cmp, bufs, i, 1) )
+        if ( copy_from_guest_offset(&cmp, bufs, i, 1) )
             return -EFAULT;
 
 #define XLAT_dm_op_buf_HNDL_h(_d_, _s_) \
diff --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h
index 8d4824f..cc99aea 100644
--- a/xen/include/xen/hypercall.h
+++ b/xen/include/xen/hypercall.h
@@ -203,7 +203,7 @@ extern int
 compat_dm_op(
     domid_t domid,
     unsigned int nr_bufs,
-    COMPAT_HANDLE_PARAM(compat_dm_op_buf_t) bufs);
+    XEN_GUEST_HANDLE_PARAM(void) bufs);
 
 #endif
 
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] x86/dmop: Fix compat_dm_op() ABI
  2017-01-31 19:59 [PATCH] x86/dmop: Fix compat_dm_op() ABI Andrew Cooper
@ 2017-02-01 10:09 ` Paul Durrant
  2017-02-01 10:44 ` Jan Beulich
  2017-02-01 10:46 ` Jan Beulich
  2 siblings, 0 replies; 6+ messages in thread
From: Paul Durrant @ 2017-02-01 10:09 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Wei Liu, Jan Beulich, Ian Jackson

> -----Original Message-----
> From: Andrew Cooper [mailto:andrew.cooper3@citrix.com]
> Sent: 31 January 2017 19:59
> To: Xen-devel <xen-devel@lists.xen.org>
> Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>; Jan Beulich
> <JBeulich@suse.com>; Paul Durrant <Paul.Durrant@citrix.com>; Ian Jackson
> <Ian.Jackson@citrix.com>; Wei Liu <wei.liu2@citrix.com>
> Subject: [PATCH] x86/dmop: Fix compat_dm_op() ABI
> 
> The parameter to compat_dm_op() is a pointer to an array of
> compat_dm_op_buf_t's in guest RAM.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Jan Beulich <JBeulich@suse.com>
> CC: Paul Durrant <paul.durrant@citrix.com>
> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
> CC: Wei Liu <wei.liu2@citrix.com>
> 
> What is the pupose of COMPAT_HANDLE_PARAM()? It is a packed structure
> of one
> and a half pointers, so isn't safe at all for use in the hypercall function
> APIs (depsite its naming making it look deceptively like it is the correct
> thing to use).

Indeed, which is why I used it... particularly as, when inspecting the auto-generated xen/include/compat/hvm/dm_op.h, the definition of struct compat_dm_op_buf is:

struct compat_dm_op_buf {
	COMPAT_HANDLE(void) h;
	compat_ulong_t size;
};
typedef struct compat_dm_op_buf compat_dm_op_buf_t;
DEFINE_COMPAT_HANDLE(compat_dm_op_buf_t);

Thus passing the bufs array as a COMPAT_HANDLE_PARAM must surely be the correct thing to, right?

> 
> On a more serious note, why do we have all this macro infrastrucutre in the
> first place?  Having spent rather longer debugging this than I to admit
> (almost mainly from the userspace side) I have concluded that it is actively
> dangerous to use; all it does is hide what is going on.
> 
> What does it actually give us that the Linux route of a real C pointers and a
> __user attribute doesn't, other than obfuscating the code on the hypercall
> boundary?
> ---
>  xen/arch/x86/hvm/dm.c       | 4 ++--
>  xen/include/xen/hypercall.h | 2 +-
>  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
> index 6a722a5..2122c45 100644
> --- a/xen/arch/x86/hvm/dm.c
> +++ b/xen/arch/x86/hvm/dm.c
> @@ -525,7 +525,7 @@ CHECK_dm_op_inject_msi;
> 
>  int compat_dm_op(domid_t domid,
>                   unsigned int nr_bufs,
> -                 COMPAT_HANDLE_PARAM(compat_dm_op_buf_t) bufs)
> +                 XEN_GUEST_HANDLE_PARAM(void) bufs)
>  {
>      struct xen_dm_op_buf nat[MAX_NR_BUFS];
>      unsigned int i;
> @@ -538,7 +538,7 @@ int compat_dm_op(domid_t domid,
>      {
>          struct compat_dm_op_buf cmp;
> 
> -        if ( copy_from_compat_offset(&cmp, bufs, i, 1) )
> +        if ( copy_from_guest_offset(&cmp, bufs, i, 1) )
>              return -EFAULT;
> 
>  #define XLAT_dm_op_buf_HNDL_h(_d_, _s_) \
> diff --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h
> index 8d4824f..cc99aea 100644
> --- a/xen/include/xen/hypercall.h
> +++ b/xen/include/xen/hypercall.h
> @@ -203,7 +203,7 @@ extern int
>  compat_dm_op(
>      domid_t domid,
>      unsigned int nr_bufs,
> -    COMPAT_HANDLE_PARAM(compat_dm_op_buf_t) bufs);
> +    XEN_GUEST_HANDLE_PARAM(void) bufs);

Shouldn't we really be fixing COMPAT_HANDLE_PARAM() to DTRT?

  Paul

> 
>  #endif
> 
> --
> 2.1.4


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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] x86/dmop: Fix compat_dm_op() ABI
  2017-01-31 19:59 [PATCH] x86/dmop: Fix compat_dm_op() ABI Andrew Cooper
  2017-02-01 10:09 ` Paul Durrant
@ 2017-02-01 10:44 ` Jan Beulich
  2017-02-01 18:29   ` Stefano Stabellini
  2017-02-01 10:46 ` Jan Beulich
  2 siblings, 1 reply; 6+ messages in thread
From: Jan Beulich @ 2017-02-01 10:44 UTC (permalink / raw)
  To: Andrew Cooper, Stefano Stabellini
  Cc: Ian Jackson, Paul Durrant, Wei Liu, Xen-devel

>>> On 31.01.17 at 20:59, <andrew.cooper3@citrix.com> wrote:
> The parameter to compat_dm_op() is a pointer to an array of
> compat_dm_op_buf_t's in guest RAM.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>
with one question (see below).

> What is the pupose of COMPAT_HANDLE_PARAM()? It is a packed structure of one
> and a half pointers, so isn't safe at all for use in the hypercall function
> APIs (depsite its naming making it look deceptively like it is the correct
> thing to use).

Stefano, you've added this in e7a527e100 ("xen: replace
XEN_GUEST_HANDLE with XEN_GUEST_HANDLE_PARAM when
appropriate"), without any user. I think it should simply be
removed.

> On a more serious note, why do we have all this macro infrastrucutre in the
> first place?  Having spent rather longer debugging this than I to admit
> (almost mainly from the userspace side) I have concluded that it is actively
> dangerous to use; all it does is hide what is going on.
> 
> What does it actually give us that the Linux route of a real C pointers and a
> __user attribute doesn't, other than obfuscating the code on the hypercall
> boundary?

I think you refer to the whole handle machinery here, the main goal
of which is to avoid anyone mistakenly directly de-referencing a
pointer coming from a guest. Linux'es __user attribute doesn't
achieve this during the normal compilation stage, afaik.

> @@ -525,7 +525,7 @@ CHECK_dm_op_inject_msi;
>  
>  int compat_dm_op(domid_t domid,
>                   unsigned int nr_bufs,
> -                 COMPAT_HANDLE_PARAM(compat_dm_op_buf_t) bufs)
> +                 XEN_GUEST_HANDLE_PARAM(void) bufs)

Why the change to void? I'd prefer if we kept correct types,
even if that's just for documentation purposes.

Jan


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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] x86/dmop: Fix compat_dm_op() ABI
  2017-01-31 19:59 [PATCH] x86/dmop: Fix compat_dm_op() ABI Andrew Cooper
  2017-02-01 10:09 ` Paul Durrant
  2017-02-01 10:44 ` Jan Beulich
@ 2017-02-01 10:46 ` Jan Beulich
  2017-02-01 12:00   ` Andrew Cooper
  2 siblings, 1 reply; 6+ messages in thread
From: Jan Beulich @ 2017-02-01 10:46 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Ian Jackson, Paul Durrant, Wei Liu, Xen-devel

>>> On 31.01.17 at 20:59, <andrew.cooper3@citrix.com> wrote:
> What is the pupose of COMPAT_HANDLE_PARAM()? It is a packed structure of one
> and a half pointers, so isn't safe at all for use in the hypercall function
> APIs (depsite its naming making it look deceptively like it is the correct
> thing to use).

Btw, where are you taking this "one and a half pointers" from?
It's half a pointer (a compat one) plus a zero sized array.

Jan


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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] x86/dmop: Fix compat_dm_op() ABI
  2017-02-01 10:46 ` Jan Beulich
@ 2017-02-01 12:00   ` Andrew Cooper
  0 siblings, 0 replies; 6+ messages in thread
From: Andrew Cooper @ 2017-02-01 12:00 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Ian Jackson, Paul Durrant, Wei Liu, Xen-devel

On 01/02/17 10:46, Jan Beulich wrote:
>>>> On 31.01.17 at 20:59, <andrew.cooper3@citrix.com> wrote:
>> What is the pupose of COMPAT_HANDLE_PARAM()? It is a packed structure of one
>> and a half pointers, so isn't safe at all for use in the hypercall function
>> APIs (depsite its naming making it look deceptively like it is the correct
>> thing to use).
> Btw, where are you taking this "one and a half pointers" from?
> It's half a pointer (a compat one) plus a zero sized array.

Hmm.  I had missed the ZLA, but debugging proves that the raw value of
bufs.c was garbage even when passing a NULL handle from userspace.  As a
result, the copy_from_compat_offset() was hitting -EFAULT for every
hypercall.

~Andrew

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] x86/dmop: Fix compat_dm_op() ABI
  2017-02-01 10:44 ` Jan Beulich
@ 2017-02-01 18:29   ` Stefano Stabellini
  0 siblings, 0 replies; 6+ messages in thread
From: Stefano Stabellini @ 2017-02-01 18:29 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, Wei Liu, Andrew Cooper, Ian Jackson,
	Xen-devel, Paul Durrant

On Wed, 1 Feb 2017, Jan Beulich wrote:
> >>> On 31.01.17 at 20:59, <andrew.cooper3@citrix.com> wrote:
> > The parameter to compat_dm_op() is a pointer to an array of
> > compat_dm_op_buf_t's in guest RAM.
> > 
> > Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> 
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
> with one question (see below).
> 
> > What is the pupose of COMPAT_HANDLE_PARAM()? It is a packed structure of one
> > and a half pointers, so isn't safe at all for use in the hypercall function
> > APIs (depsite its naming making it look deceptively like it is the correct
> > thing to use).
> 
> Stefano, you've added this in e7a527e100 ("xen: replace
> XEN_GUEST_HANDLE with XEN_GUEST_HANDLE_PARAM when
> appropriate"), without any user. I think it should simply be
> removed.

I think I added it for completeness: hypercalls parameters which are
pointers are supposed to be declared using _PARAM macros, because on arm
they have a different size compared to their corresponding
XEN_GUEST_HANDLE type (4 bytes vs 8 bytes). Unfortunately, forgetting to
convert an hypercall parameter type to _PARAM doesn't result in a build
failure, but in a much less obvious runtime failure when the hypercall
is called.

Compat hypercalls are not used on ARM, but for consistency I thought it
would be a good idea to mark their hypercall parameters as "_PARAM".

To do that, I introduced the COMPAT_HANDLE_PARAM macro, whose only
purpose is to be have "_PARAM" in its name. It is not necessary in
compat_dm_op from an ABI point of view, but it properly marks the third
parameter as an hypercall parameter.

I am OK with removing COMPAT_HANDLE_PARAM, but please carefully use the
appropriate XEN_GUEST_HANDLE_PARAM type (avoid directly using
XEN_GUEST_HANDLE) in its stead.


> > On a more serious note, why do we have all this macro infrastrucutre in the
> > first place?  Having spent rather longer debugging this than I to admit
> > (almost mainly from the userspace side) I have concluded that it is actively
> > dangerous to use; all it does is hide what is going on.
> > 
> > What does it actually give us that the Linux route of a real C pointers and a
> > __user attribute doesn't, other than obfuscating the code on the hypercall
> > boundary?
> 
> I think you refer to the whole handle machinery here, the main goal
> of which is to avoid anyone mistakenly directly de-referencing a
> pointer coming from a guest. Linux'es __user attribute doesn't
> achieve this during the normal compilation stage, afaik.

Additionally, XEN_GUEST_HANDLE_PARAM and XEN_GUEST_HANDLE differ on ARM.


> > @@ -525,7 +525,7 @@ CHECK_dm_op_inject_msi;
> >  
> >  int compat_dm_op(domid_t domid,
> >                   unsigned int nr_bufs,
> > -                 COMPAT_HANDLE_PARAM(compat_dm_op_buf_t) bufs)
> > +                 XEN_GUEST_HANDLE_PARAM(void) bufs)
> 
> Why the change to void? I'd prefer if we kept correct types,
> even if that's just for documentation purposes.

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-02-01 18:29 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-31 19:59 [PATCH] x86/dmop: Fix compat_dm_op() ABI Andrew Cooper
2017-02-01 10:09 ` Paul Durrant
2017-02-01 10:44 ` Jan Beulich
2017-02-01 18:29   ` Stefano Stabellini
2017-02-01 10:46 ` Jan Beulich
2017-02-01 12:00   ` Andrew Cooper

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.