[Qemu-devel] [PATCH v2 2/2] Xen: Use the ioreq-server API when available
The ioreq-server API added to Xen 4.5 offers better security than the existing Xen/QEMU interface because the shared pages that are used to pass emulation request/results back and forth are removed from the guest's memory space before any requests are serviced. This prevents the guest from mapping these pages (they are in a well known location) and attempting to attack QEMU by synthesizing its own request structures. Hence, this patch modifies configure to detect whether the API is available, and adds the necessary code to use the API if it is. Signed-off-by: Paul Durrant paul.durr...@citrix.com Cc: Stefano Stabellini stefano.stabell...@eu.citrix.com Cc: Peter Maydell peter.mayd...@linaro.org Cc: Paolo Bonzini pbonz...@redhat.com Cc: Michael Tokarev m...@tls.msk.ru Cc: Stefan Hajnoczi stefa...@redhat.com Cc: Stefan Weil s...@weilnetz.de Cc: Olaf Hering o...@aepfle.de Cc: Gerd Hoffmann kra...@redhat.com Cc: Alexey Kardashevskiy a...@ozlabs.ru Cc: Alexander Graf ag...@suse.de --- configure | 29 ++ include/hw/xen/xen_common.h | 222 +++ trace-events|8 ++ xen-hvm.c | 163 +++ 4 files changed, 403 insertions(+), 19 deletions(-) diff --git a/configure b/configure index 9ac2600..c2db574 100755 --- a/configure +++ b/configure @@ -1876,6 +1876,32 @@ int main(void) { xc_gnttab_open(NULL, 0); xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0); xc_hvm_inject_msi(xc, 0, 0xf000, 0x); + xc_hvm_create_ioreq_server(xc, 0, 0, NULL); + return 0; +} +EOF + compile_prog $xen_libs +then +xen_ctrl_version=450 +xen=yes + + elif + cat $TMPC EOF +#include xenctrl.h +#include xenstore.h +#include stdint.h +#include xen/hvm/hvm_info_table.h +#if !defined(HVM_MAX_VCPUS) +# error HVM_MAX_VCPUS not defined +#endif +int main(void) { + xc_interface *xc; + xs_daemon_open(); + xc = xc_interface_open(0, 0, 0); + xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + xc_gnttab_open(NULL, 0); + xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0); + xc_hvm_inject_msi(xc, 0, 0xf000, 0x); return 0; } EOF @@ -4282,6 +4308,9 @@ if test -n $sparc_cpu; then echo Target Sparc Arch $sparc_cpu fi echo xen support $xen +if test $xen = yes ; then + echo xen ctrl version $xen_ctrl_version +fi echo brlapi support$brlapi echo bluez support$bluez echo Documentation $docs diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h index 07731b9..7040506 100644 --- a/include/hw/xen/xen_common.h +++ b/include/hw/xen/xen_common.h @@ -16,7 +16,9 @@ #include hw/hw.h #include hw/xen/xen.h +#include hw/pci/pci.h #include qemu/queue.h +#include trace.h /* * We don't support Xen prior to 3.3.0. @@ -164,4 +166,224 @@ void destroy_hvm_domain(bool reboot); /* shutdown/destroy current domain because of an error */ void xen_shutdown_fatal_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2); +/* Xen before 4.5 */ +#if CONFIG_XEN_CTRL_INTERFACE_VERSION 450 + +#ifndef HVM_PARAM_BUFIOREQ_EVTCHN +#define HVM_PARAM_BUFIOREQ_EVTCHN 26 +#endif + +#define IOREQ_TYPE_PCI_CONFIG 2 + +typedef uint32_t ioservid_t; + +static inline void xen_map_memory_section(XenXC xc, domid_t dom, + ioservid_t ioservid, + MemoryRegionSection *section) +{ +} + +static inline void xen_unmap_memory_section(XenXC xc, domid_t dom, +ioservid_t ioservid, +MemoryRegionSection *section) +{ +} + +static inline void xen_map_io_section(XenXC xc, domid_t dom, + ioservid_t ioservid, + MemoryRegionSection *section) +{ +} + +static inline void xen_unmap_io_section(XenXC xc, domid_t dom, +ioservid_t ioservid, +MemoryRegionSection *section) +{ +} + +static inline void xen_map_pcidev(XenXC xc, domid_t dom, + ioservid_t ioservid, + PCIDevice *pci_dev) +{ +} + +static inline void xen_unmap_pcidev(XenXC xc, domid_t dom, +ioservid_t ioservid, +PCIDevice *pci_dev) +{ +} + +static inline int xen_create_ioreq_server(XenXC xc, domid_t dom, + ioservid_t *ioservid) +{ +return 0; +} + +static inline void xen_destroy_ioreq_server(XenXC xc, domid_t dom, +ioservid_t ioservid) +{ +} + +static inline int xen_get_ioreq_server_info(XenXC xc, domid_t dom, +ioservid_t ioservid, +xen_pfn_t *ioreq_pfn, +xen_pfn_t
Re: [Qemu-devel] [PATCH v2 2/2] Xen: Use the ioreq-server API when available
On Mon, 13 Oct 2014, Paul Durrant wrote: The ioreq-server API added to Xen 4.5 offers better security than the existing Xen/QEMU interface because the shared pages that are used to pass emulation request/results back and forth are removed from the guest's memory space before any requests are serviced. This prevents the guest from mapping these pages (they are in a well known location) and attempting to attack QEMU by synthesizing its own request structures. Hence, this patch modifies configure to detect whether the API is available, and adds the necessary code to use the API if it is. Signed-off-by: Paul Durrant paul.durr...@citrix.com I think the patch is pretty good, just one comment below. Cc: Stefano Stabellini stefano.stabell...@eu.citrix.com Cc: Peter Maydell peter.mayd...@linaro.org Cc: Paolo Bonzini pbonz...@redhat.com Cc: Michael Tokarev m...@tls.msk.ru Cc: Stefan Hajnoczi stefa...@redhat.com Cc: Stefan Weil s...@weilnetz.de Cc: Olaf Hering o...@aepfle.de Cc: Gerd Hoffmann kra...@redhat.com Cc: Alexey Kardashevskiy a...@ozlabs.ru Cc: Alexander Graf ag...@suse.de --- configure | 29 ++ include/hw/xen/xen_common.h | 222 +++ trace-events|8 ++ xen-hvm.c | 163 +++ 4 files changed, 403 insertions(+), 19 deletions(-) diff --git a/configure b/configure index 9ac2600..c2db574 100755 --- a/configure +++ b/configure @@ -1876,6 +1876,32 @@ int main(void) { xc_gnttab_open(NULL, 0); xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0); xc_hvm_inject_msi(xc, 0, 0xf000, 0x); + xc_hvm_create_ioreq_server(xc, 0, 0, NULL); + return 0; +} +EOF + compile_prog $xen_libs +then +xen_ctrl_version=450 +xen=yes + + elif + cat $TMPC EOF +#include xenctrl.h +#include xenstore.h +#include stdint.h +#include xen/hvm/hvm_info_table.h +#if !defined(HVM_MAX_VCPUS) +# error HVM_MAX_VCPUS not defined +#endif +int main(void) { + xc_interface *xc; + xs_daemon_open(); + xc = xc_interface_open(0, 0, 0); + xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + xc_gnttab_open(NULL, 0); + xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0); + xc_hvm_inject_msi(xc, 0, 0xf000, 0x); return 0; } EOF @@ -4282,6 +4308,9 @@ if test -n $sparc_cpu; then echo Target Sparc Arch $sparc_cpu fi echo xen support $xen +if test $xen = yes ; then + echo xen ctrl version $xen_ctrl_version +fi echo brlapi support$brlapi echo bluez support$bluez echo Documentation $docs diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h index 07731b9..7040506 100644 --- a/include/hw/xen/xen_common.h +++ b/include/hw/xen/xen_common.h @@ -16,7 +16,9 @@ #include hw/hw.h #include hw/xen/xen.h +#include hw/pci/pci.h #include qemu/queue.h +#include trace.h /* * We don't support Xen prior to 3.3.0. @@ -164,4 +166,224 @@ void destroy_hvm_domain(bool reboot); /* shutdown/destroy current domain because of an error */ void xen_shutdown_fatal_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2); +/* Xen before 4.5 */ +#if CONFIG_XEN_CTRL_INTERFACE_VERSION 450 + +#ifndef HVM_PARAM_BUFIOREQ_EVTCHN +#define HVM_PARAM_BUFIOREQ_EVTCHN 26 +#endif + +#define IOREQ_TYPE_PCI_CONFIG 2 + +typedef uint32_t ioservid_t; + +static inline void xen_map_memory_section(XenXC xc, domid_t dom, + ioservid_t ioservid, + MemoryRegionSection *section) +{ +} + +static inline void xen_unmap_memory_section(XenXC xc, domid_t dom, +ioservid_t ioservid, +MemoryRegionSection *section) +{ +} + +static inline void xen_map_io_section(XenXC xc, domid_t dom, + ioservid_t ioservid, + MemoryRegionSection *section) +{ +} + +static inline void xen_unmap_io_section(XenXC xc, domid_t dom, +ioservid_t ioservid, +MemoryRegionSection *section) +{ +} + +static inline void xen_map_pcidev(XenXC xc, domid_t dom, + ioservid_t ioservid, + PCIDevice *pci_dev) +{ +} + +static inline void xen_unmap_pcidev(XenXC xc, domid_t dom, +ioservid_t ioservid, +PCIDevice *pci_dev) +{ +} + +static inline int xen_create_ioreq_server(XenXC xc, domid_t dom, + ioservid_t *ioservid) +{ +return 0; +} + +static inline void xen_destroy_ioreq_server(XenXC xc, domid_t dom, +ioservid_t ioservid) +{ +} +
Re: [Qemu-devel] [PATCH v2 2/2] Xen: Use the ioreq-server API when available
-Original Message- From: Stefano Stabellini [mailto:stefano.stabell...@eu.citrix.com] Sent: 13 October 2014 16:53 To: Paul Durrant Cc: qemu-devel@nongnu.org; xen-de...@lists.xenproject.org; Stefano Stabellini; Peter Maydell; Paolo Bonzini; Michael Tokarev; Stefan Hajnoczi; Stefan Weil; Olaf Hering; Gerd Hoffmann; Alexey Kardashevskiy; Alexander Graf Subject: Re: [PATCH v2 2/2] Xen: Use the ioreq-server API when available On Mon, 13 Oct 2014, Paul Durrant wrote: The ioreq-server API added to Xen 4.5 offers better security than the existing Xen/QEMU interface because the shared pages that are used to pass emulation request/results back and forth are removed from the guest's memory space before any requests are serviced. This prevents the guest from mapping these pages (they are in a well known location) and attempting to attack QEMU by synthesizing its own request structures. Hence, this patch modifies configure to detect whether the API is available, and adds the necessary code to use the API if it is. Signed-off-by: Paul Durrant paul.durr...@citrix.com I think the patch is pretty good, just one comment below. [snip] @@ -487,9 +494,52 @@ static void xen_region_del(MemoryListener *listener, MemoryRegionSection *section) { xen_set_memory(listener, section, false); + +if (section-mr != ram_memory) { +XenIOState *state = container_of(listener, XenIOState, memory_listener); + +xen_unmap_memory_section(xen_xc, xen_domid, state-ioservid, section); +} + memory_region_unref(section-mr); } I would prefer if you could move the xen_unmap_memory_section and xen_map_memory_section calls to xen_set_memory, where we already have a ram_memory check. Could you reuse it? Sure, I can do that. Paul