All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christopher Clark <christopher.w.clark@gmail.com>
To: Jan Beulich <JBeulich@suse.com>
Cc: Tim Deegan <tim@xen.org>,
	Stefano Stabellini <sstabellini@kernel.org>,
	Wei Liu <wei.liu2@citrix.com>,
	Ross Philipson <ross.philipson@gmail.com>,
	Jason Andryuk <jandryuk@gmail.com>,
	Daniel Smith <dpsmith@apertussolutions.com>,
	Andrew Cooper <andrew.cooper3@citrix.com>,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
	Ian Jackson <Ian.Jackson@eu.citrix.com>,
	Rich Persaud <persaur@gmail.com>,
	James McKenzie <james@bromium.com>,
	George Dunlap <George.Dunlap@eu.citrix.com>,
	Julien Grall <julien.grall@arm.com>,
	Paul Durrant <paul.durrant@citrix.com>,
	xen-devel <xen-devel@lists.xenproject.org>,
	eric chanudet <eric.chanudet@gmail.com>,
	Roger Pau Monne <roger.pau@citrix.com>
Subject: Re: [PATCH v3 15/15] argo: validate hypercall arg structures via compat machinery
Date: Sun, 20 Jan 2019 13:18:22 -0800	[thread overview]
Message-ID: <CACMJ4Ga6-DsAnQSwM-TFJ+FSh0AHzNp44FORP6D5LVAKiu-s_Q@mail.gmail.com> (raw)
In-Reply-To: <5C406633020000780020E9BC@prv1-mh.provo.novell.com>

On Thu, Jan 17, 2019 at 3:25 AM Jan Beulich <JBeulich@suse.com> wrote:
>
> >>> On 17.01.19 at 08:22, <christopher.w.clark@gmail.com> wrote:
> > Some details of the problem:
> >
> > Without the macro overrides in place (ie. using the existing
> > definitions) the build fails on CHECK_argo_send_addr  because this
> > struct is defined with types that are themselves translated by the
> > compat processing:
>
> But that's a normal situation.

I thought it would be too but I haven't found a direct equivalent to
what this header needs. I'll outline the results of my examination
below.

>
> > typedef struct xen_argo_send_addr
> > {
> >     xen_argo_addr_t src;
> >     xen_argo_addr_t dst;
> > } xen_argo_send_addr_t;
> >
> > compat/argo.c: In function '__checkFstruct_argo_send_addr__src':
> > xen/include/xen/compat.h:170:18: error: comparison of distinct pointer
> > types lacks a cast [-Werror]
> >      return &x->f == &c->f; \
> >                   ^
> > xen/include/xen/compat.h:176:5: note: in expansion of macro
> > 'CHECK_FIELD_COMMON_'
> >      CHECK_FIELD_COMMON_(k, CHECK_NAME_(k, n ## __ ## f, F), n, f)
> >      ^~~~~~~~~~~~~~~~~~~
> > xen/include/compat/xlat.h:1238:5: note: in expansion of macro 'CHECK_FIELD_'
> >      CHECK_FIELD_(struct, argo_send_addr, src); \
> >      ^~~~~~~~~~~~
> > compat/argo.c:43:1: note: in expansion of macro 'CHECK_argo_send_addr'
> >  CHECK_argo_send_addr;
> >  ^~~~~~~~~~~~~~~~~~~~
> >
> > because xen_argo_addr_t is detected as a different type than
> > compat_argo_addr_t -- when in practice is the same size and has the
> > same fields at the same offsets.
>
> Did you perhaps not add entries for the inner structures to xlat.lst?

No, unfortunately I did.

Here are my findings after exploring the compat machinery, in relation
to understanding its processing of the the Argo public header file, and
its production of the compat header file and validation macros.

1) Two alternative validation macros are possible as output, depending
on how struct fields are declared within structs in the input header.

Struct fields that are themselves structs can be declared two different
ways:

* by type (I'll call this "type form"): xen_mystruct_t field;

eg.
    typedef struct xen_argo_send_addr
    {
        xen_argo_addr_t src;
        xen_argo_addr_t dst;
    } xen_argo_send_addr_t;


* by struct name ("struct form"): struct xen_mystruct field;

eg.
    typedef struct xen_argo_send_addr
    {
        struct xen_argo_addr src;
        struct xen_argo_addr dst;
    } xen_argo_send_addr_t;


In the validation macros that are produced for xen_argo_send_addr, the
"struct form" contains:
    CHECK_mystruct;

and the "type form" contains instead:
    CHECK_FIELD_(struct, mystruct, field);

These two validation macros do different things; the CHECK_FIELD one
is stronger because it tests that the offset, size and type of the
field match, whereas the other checks the structure of the inner struct,
but not its placement within the outer or matching type in compat vs
non-compat.

After reviewing other public headers within Xen and the structs in the
xlat.lst list, it looks like some existing structs are passing
CHECKs by using the "struct" form, even though the checks are weaker.


2. The "type form" checks cannot work for fields that are themselves
compat-translated.

For fields that are struct types that are themselves compat-translated,
the CHECK_FIELD fails because it does a typeof check in the macro,
which cannot pass since the non-compat type will never equal the
compat-type -- the fields really are different types.

So when defining a struct field with a type that will be translated,
you have to declare them using the "struct" form, not the "type" form.

A prior example of this is: struct mcinfo_extended
which declares an array field using the struct form, and not its type.

A problem with what the "struct" form generates is that the test that it
produces doesn't check the offset of the field within the struct it
belongs to. Enabling CHECK_FIELD to work looks preferable as it
provides better assurance of correctness.

One way to make CHECK_FIELD work is to override the CHECK_COMMON macro,
and disable the typeof check when necessary, as has been presented in
the versions of the Argo patch series so far.


3. A challenge with using the "struct" form, following from the result
of point 2, occurs when it's a XEN_GUEST_HANDLE field within the struct.
It's not obvious how to declare that field using the "struct" form
rather than the "type" form.
This affects the argo_iov struct.

4. Macros to perform "struct form" checks cannot be repeated.

When using the "struct" form, it's problem when the struct contains two
fields of the same compat-translated type.

eg. consider the "struct form" version of xen_argo_send_addr, which has
two fields of struct xen_argo_addr:

    typedef struct xen_argo_send_addr
    {
        struct xen_argo_addr src;
        struct xen_argo_addr dst;
    } xen_argo_send_addr_t;

which then generates this in the compat header:

    #define CHECK_argo_send_addr \
        CHECK_SIZE_(struct, argo_send_addr); \
        CHECK_argo_addr; \
        CHECK_argo_addr

and the second macro invocation of CHECK_argo_addr just breaks, with the
build failing due to redefinition of a symbol that is already defined.

A (horrible, unacceptable) workaround that unblocks further discovery
is to redefine xen_argo_send_addr to use an array:

typedef struct xen_argo_send_addr
{
    struct xen_argo_addr addrs[2];
} xen_argo_send_addr_t;

which does pass, since it now generates this:

#define CHECK_argo_send_addr \
    CHECK_SIZE_(struct, argo_send_addr); \
    CHECK_argo_addr

and then CHECK_argo_send_addr passes, *but* the fields are no longer
named as they should be, which is not OK.

The "no repeated checks" problem also occurs when another separate
struct contains a field of a type that has already been checked:
whichever CHECK is performed second will break.

eg.
typedef struct xen_argo_ring_data_ent
{
    struct xen_argo_addr ring;
    uint16_t flags;
    uint16_t pad;
    uint32_t space_required;
    uint32_t max_message_size;
} xen_argo_ring_data_ent_t;

also has a field of type xen_argo_addr, which produces CHECK_argo_addr,
which then fails because that was already tested in
CHECK_argo_send_addr.

Anyway, hopefully this provides context for evaluating the method of
passing the compat tests that has been proposed in the Argo series:
selective override of the CHECK_FIELD_COMMON macro to disable the typeof
checks only for validating those structs that require it to be turned
off.


> >> > --- a/xen/common/Makefile
> >> > +++ b/xen/common/Makefile
> >> > @@ -70,7 +70,7 @@ obj-y += xmalloc_tlsf.o
> >> >  obj-bin-$(CONFIG_X86) += $(foreach n,decompress bunzip2 unxz unlzma unlzo unlz4 earlycpio,$(n).init.o)
> >> >
> >> >
> >> > -obj-$(CONFIG_COMPAT) += $(addprefix compat/,domain.o kernel.o memory.o multicall.o xlat.o)
> >> > +obj-$(CONFIG_COMPAT) += $(addprefix compat/,argo.o domain.o kernel.o memory.o multicall.o xlat.o)
> >>
> >> While a matter of taste to a certain degree, I'm not convinced
> >> introducing a separate file for this is really necessary, especially
> >> if some of the overrides to the CHECK_* macros would go away.
> >
> > ack. I wouldn't have moved them out if the overrides weren't in use;
> > but I will merge it into the implementation file if that is preferred.
>
> Well - let's first see whether the overrides are really needed. If so,
> keeping this in a separate file might indeed be better.

ack.

Christopher

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

  reply	other threads:[~2019-01-20 21:18 UTC|newest]

Thread overview: 104+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-07  7:42 [PATCH v3 00/15] Argo: hypervisor-mediated interdomain communication Christopher Clark
2019-01-07  7:42 ` [PATCH v3 01/15] argo: Introduce the Kconfig option to govern inclusion of Argo Christopher Clark
2019-01-08 15:46   ` Jan Beulich
2019-01-07  7:42 ` [PATCH v3 02/15] argo: introduce the argo_op hypercall boilerplate Christopher Clark
2019-01-07  7:42 ` [PATCH v3 03/15] argo: define argo_dprintk for subsystem debugging Christopher Clark
2019-01-08 15:50   ` Jan Beulich
2019-01-10  9:28   ` Roger Pau Monné
2019-01-07  7:42 ` [PATCH v3 04/15] argo: init, destroy and soft-reset, with enable command line opt Christopher Clark
2019-01-08 22:08   ` Ross Philipson
2019-01-08 22:23     ` Christopher Clark
2019-01-08 22:54   ` Jason Andryuk
2019-01-09  6:48     ` Christopher Clark
2019-01-09 14:15       ` Jason Andryuk
2019-01-09 23:24         ` Christopher Clark
2019-01-09  9:35     ` Jan Beulich
2019-01-09 14:26       ` Jason Andryuk
2019-01-09 14:38         ` Jan Beulich
2019-01-10 23:29           ` Christopher Clark
2019-01-10 10:19   ` Roger Pau Monné
2019-01-10 11:52     ` Jan Beulich
2019-01-10 12:26       ` Roger Pau Monné
2019-01-10 12:46         ` Jan Beulich
2019-01-11  6:03     ` Christopher Clark
2019-01-11  9:27       ` Roger Pau Monné
2019-01-14  8:32         ` Christopher Clark
2019-01-14 11:32           ` Roger Pau Monné
2019-01-14 14:28             ` Rich Persaud
2019-01-10 16:16   ` Eric Chanudet
2019-01-11  6:05     ` Christopher Clark
2019-01-11 11:54   ` Jan Beulich
2019-01-14  8:33     ` Christopher Clark
2019-01-14 14:46   ` Wei Liu
2019-01-14 15:29     ` Lars Kurth
2019-01-14 18:16     ` Christopher Clark
2019-01-14 19:42     ` Roger Pau Monné
2019-02-04 20:56     ` Christopher Clark
2019-02-05 10:32       ` Wei Liu
2019-01-14 14:58   ` Andrew Cooper
2019-01-14 15:12     ` Jan Beulich
2019-01-15  7:24       ` Christopher Clark
2019-01-15  7:21     ` Christopher Clark
2019-01-15  9:01       ` Jan Beulich
2019-01-15  9:06         ` Andrew Cooper
2019-01-15  9:17           ` Jan Beulich
2019-01-07  7:42 ` [PATCH v3 05/15] errno: add POSIX error codes EMSGSIZE, ECONNREFUSED to the ABI Christopher Clark
2019-01-07  7:42 ` [PATCH v3 06/15] xen/arm: introduce guest_handle_for_field() Christopher Clark
2019-01-08 22:03   ` Stefano Stabellini
2019-01-07  7:42 ` [PATCH v3 07/15] argo: implement the register op Christopher Clark
2019-01-09 15:55   ` Wei Liu
2019-01-09 16:00     ` Christopher Clark
2019-01-09 17:02       ` Julien Grall
2019-01-09 17:18         ` Stefano Stabellini
2019-01-09 18:13           ` Julien Grall
2019-01-09 20:33             ` Christopher Clark
2019-01-09 17:54         ` Wei Liu
2019-01-09 18:28           ` Julien Grall
2019-01-09 20:38             ` Christopher Clark
2019-01-10 11:24   ` Roger Pau Monné
2019-01-10 11:57     ` Jan Beulich
2019-01-11  6:30       ` Christopher Clark
2019-01-11  6:29     ` Christopher Clark
2019-01-11  9:38       ` Roger Pau Monné
2019-01-10 20:11   ` Eric Chanudet
2019-01-11  6:09     ` Christopher Clark
2019-01-14 14:19   ` Jan Beulich
2019-01-15  7:56     ` Christopher Clark
2019-01-15  8:36       ` Jan Beulich
2019-01-15  8:46         ` Christopher Clark
2019-01-14 15:31   ` Andrew Cooper
2019-01-15  8:02     ` Christopher Clark
2019-01-07  7:42 ` [PATCH v3 08/15] argo: implement the unregister op Christopher Clark
2019-01-10 11:40   ` Roger Pau Monné
2019-01-15  8:05     ` Christopher Clark
2019-01-14 15:06   ` Jan Beulich
2019-01-15  8:11     ` Christopher Clark
2019-01-07  7:42 ` [PATCH v3 09/15] argo: implement the sendv op; evtchn: expose send_guest_global_virq Christopher Clark
2019-01-09 18:05   ` Jason Andryuk
2019-01-10  2:08     ` Christopher Clark
2019-01-09 18:57   ` Roger Pau Monné
2019-01-10  3:09     ` Christopher Clark
2019-01-10 12:01       ` Roger Pau Monné
2019-01-10 12:13         ` Jan Beulich
2019-01-10 12:40           ` Roger Pau Monné
2019-01-10 12:53             ` Jan Beulich
2019-01-11  6:37               ` Christopher Clark
2019-01-10 21:41   ` Eric Chanudet
2019-01-11  7:12     ` Christopher Clark
2019-01-07  7:42 ` [PATCH v3 10/15] argo: implement the notify op Christopher Clark
2019-01-10 12:21   ` Roger Pau Monné
2019-01-15  6:53     ` Christopher Clark
2019-01-15  8:06       ` Roger Pau Monné
2019-01-15  8:32         ` Christopher Clark
2019-01-07  7:42 ` [PATCH v3 11/15] xsm, argo: XSM control for argo register Christopher Clark
2019-01-07  7:42 ` [PATCH v3 12/15] xsm, argo: XSM control for argo message send operation Christopher Clark
2019-01-07  7:42 ` [PATCH v3 13/15] xsm, argo: XSM control for any access to argo by a domain Christopher Clark
2019-01-07  7:42 ` [PATCH v3 14/15] xsm, argo: notify: don't describe rings that cannot be sent to Christopher Clark
2019-01-07  7:42 ` [PATCH v3 15/15] argo: validate hypercall arg structures via compat machinery Christopher Clark
2019-01-14 12:57   ` Jan Beulich
2019-01-17  7:22     ` Christopher Clark
2019-01-17 11:25       ` Jan Beulich
2019-01-20 21:18         ` Christopher Clark [this message]
2019-01-21 12:03           ` Jan Beulich
2019-01-22 11:08             ` Jan Beulich
2019-01-23 21:14               ` Christopher Clark

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=CACMJ4Ga6-DsAnQSwM-TFJ+FSh0AHzNp44FORP6D5LVAKiu-s_Q@mail.gmail.com \
    --to=christopher.w.clark@gmail.com \
    --cc=George.Dunlap@eu.citrix.com \
    --cc=Ian.Jackson@eu.citrix.com \
    --cc=JBeulich@suse.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=dpsmith@apertussolutions.com \
    --cc=eric.chanudet@gmail.com \
    --cc=james@bromium.com \
    --cc=jandryuk@gmail.com \
    --cc=julien.grall@arm.com \
    --cc=konrad.wilk@oracle.com \
    --cc=paul.durrant@citrix.com \
    --cc=persaur@gmail.com \
    --cc=roger.pau@citrix.com \
    --cc=ross.philipson@gmail.com \
    --cc=sstabellini@kernel.org \
    --cc=tim@xen.org \
    --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 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.