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

Re: [Xen-devel] [GSoC] GSoC Introduction : Fuzzing Xen hypercall interface




2017-03-20 17:18 GMT+01:00 Wei Liu <wei.liu2@xxxxxxxxxx>:
On Mon, Mar 20, 2017 at 09:12:54AM +0100, Felix Schmoll wrote:
> 2017-03-16 17:27 GMT+01:00 Wei Liu <wei.liu2@xxxxxxxxxx>:
>
>  #undef COMP
> diff --git a/xen/common/kernel.c b/xen/common/kernel.c
> index 4b87c60845..de07ee529b 100644
> --- a/xen/common/kernel.c
> +++ b/xen/common/kernel.c
> @@ -226,6 +226,12 @@ void __init do_initcalls(void)
>   * Simple hypercalls.
>   */
>
> +DO(domain_id)(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)

XEN_GUEST_HANDLE_PARAM means arg is a pointer to void type inside of the
guest, it's better to just use XEN_GUEST_HANDLE_PARAM(uint32_t) arg.
Also see below.

> +{
> +    struct domain *d = current->domain;
> +    return d->domain_id;

You certainly don't need cmd, because you provide no command.

If you want to return the domain id directly, you don't need arg.
Also please be aware of the types (long vs uint32_t). I think this is
the simplest approach.

> +}
> +
>  DO(xen_version)(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
>  {
>      bool_t deny = !!xsm_xen_version(XSM_OTHER, cmd);
> diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
> index 91ba8bb48e..4ad62aa01b 100644
> --- a/xen/include/public/xen.h
> +++ b/xen/include/public/xen.h
> @@ -121,6 +121,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
>  #define __HYPERVISOR_xc_reserved_op       39 /* reserved for XenClient */
>  #define __HYPERVISOR_xenpmu_op            40
>  #define __HYPERVISOR_dm_op                41
> +#define __HYPERVISOR_domain_id            42 /* custom hypercall */
>
>  /* Architecture-specific hypercall definitions. */
>  #define __HYPERVISOR_arch_0               48
> diff --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h
> index cc99aea57d..438684df85 100644
> --- a/xen/include/xen/hypercall.h
> +++ b/xen/include/xen/hypercall.h
> @@ -83,6 +83,11 @@ do_xen_version(
>      XEN_GUEST_HANDLE_PARAM(void) arg);
>
>  extern long
> +do_domain_id(
> +    int cmd,
> +    XEN_GUEST_HANDLE_PARAM(void) arg);
> +
> +extern long
>  do_console_io(
>      int cmd,
>      int count,
> --
> 2.11.0
>
>
> From 3a896fcf3bc5d7f8c4613d9d4b854684ec981e7f Mon Sep 17 00:00:00 2001
> From: Felix Schmoll <eggi.innovations@xxxxxxxxx>
> Date: Thu, 16 Mar 2017 22:38:23 +0100
> Subject: [PATCH 2/2] Adjust libxc to new hypercall (untested)
>
> ---
>  tools/libxc/include/xenctrl.h |  1 +
>  tools/libxc/xc_private.c      | 17 +++++++++++++++++
>  tools/libxc/xc_private.h      |  8 ++++++++
>  3 files changed, 26 insertions(+)
>
> diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
> index a48981abea..e454b10f64 100644
> --- a/tools/libxc/include/xenctrl.h
> +++ b/tools/libxc/include/xenctrl.h
> @@ -1546,6 +1546,7 @@ int xc_domctl(xc_interface *xch, struct xen_domctl
> *domctl);
>  int xc_sysctl(xc_interface *xch, struct xen_sysctl *sysctl);
>
>  int xc_version(xc_interface *xch, int cmd, void *arg);
> +int xc_domid(xc_interface *xch, int cmd, void *arg);
>
>  int xc_flask_op(xc_interface *xch, xen_flask_op_t *op);
>
> diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c
> index 72e6242417..f4f158c661 100644
> --- a/tools/libxc/xc_private.c
> +++ b/tools/libxc/xc_private.c
> @@ -530,6 +530,23 @@ int xc_version(xc_interface *xch, int cmd, void *arg)
>      return rc;
>  }
>
> +int xc_domid(xc_interface *xch, int cmd, void *arg)
> +{
> +    DECLARE_HYPERCALL_BOUNCE(arg, 0, XC_HYPERCALL_BUFFER_BOUNCE_OUT); /*
> Size unknown until cmd decoded */
> +    size_t sz;
> +    int rc;
> +
> +    /* TODO: might want to either consider or remove cmd param */
> +    sz = 0;
> +
> +    HYPERCALL_BOUNCE_SET_SIZE(arg, sz);
> +
> +    rc = do_domain_id(xch, cmd, HYPERCALL_BUFFER(arg));

Most likely you will get rc = 0 because you're running your test program
in Dom0. Try running this a DomU?

> +
> +    return rc;
> +}
> +
> +
>  unsigned long xc_make_page_below_4G(
>      xc_interface *xch, uint32_t domid, unsigned long mfn)
>  {
> diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
> index 1c27b0fded..7cf875ffb5 100644
> --- a/tools/libxc/xc_private.h
> +++ b/tools/libxc/xc_private.h
> @@ -229,6 +229,14 @@ static inline int do_xen_version(xc_interface *xch,
> int cmd, xc_hypercall_buffer
>                      cmd, HYPERCALL_BUFFER_AS_ARG(dest));
>  }
>
> +/* custom hypercall */
> +static inline int do_domain_id(xc_interface *xch, int cmd,
> xc_hypercall_buffer_t *dest)
> +{
> +    DECLARE_HYPERCALL_BUFFER_ARGUMENT(dest);
> +    return xencall2(xch->xcall, __HYPERVISOR_domain_id,
> +                    cmd, HYPERCALL_BUFFER_AS_ARG(dest));
> +}
> +
>  static inline int do_physdev_op(xc_interface *xch, int cmd, void *op,
> size_t len)
>  {
>      int ret = -1;
> --
> 2.11.0
>
> Now the question is how do I debug the hypercall. I compared what I have to
> xen_version and to the patch for the last implemented hypercall but you
> seem to have slightly changed the entry into to hypervisor since then. I
> could use gdb for debugging the libxc-part, and printk is fine for the
> kernel, but can you either point me to some discussion of the call-chain or
> to some sort of debugger.
>

You can't attach a debugger to hypervisor. You can use printk in
hypervisor to debug.

Hypercall is just like syscall. You cross the boundary of different
privilege levels. You've already identified the C entry point
(x86/hypercall.c). For the ASM entry point, the PV one is in
arch/x86/x86_64/entry.S and the HVM one is in arch/x86/hvm/vmx/vmx.c
(Intel CPU) and arch/x86/svm/svm.c (AMD CPU). I don't think you need to
care about the ASM entry points though.

Please always develop against xen.git staging branch.

I don't follow why your code doesn't work for you. Can you be more
specific?

It returns -1 when I run the following program:

#include <stdio.h>
#include <xenctrl.h>

int main(void) {
    xc_interface *xch = xc_interface_open(NULL, NULL, 0);

    int ver = xc_version(xch, XENVER_version, NULL);

    printf("Xen Version %d.%d\n", ver >> 16, ver & 0xffff);

    int domid = xc_domid(xch, 0, NULL);

    printf("Xen domain: %d\n", domid);

    xc_interface_close(xch);

    return 0;
}

Wei.

> Any comments greatly appreciated.
>
> Felix

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

 


Rackspace

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