xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] Fix QEMU crashes when passing IGD to a guest VM under XEN
@ 2020-04-28  6:28 Grzegorz Uriasz
  2020-04-28  6:28 ` [PATCH 1/2] Fix undefined behaviour Grzegorz Uriasz
  2020-04-28  6:28 ` [PATCH 2/2] Improve legacy vbios handling Grzegorz Uriasz
  0 siblings, 2 replies; 8+ messages in thread
From: Grzegorz Uriasz @ 2020-04-28  6:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: artur, Stefano Stabellini, Paul Durrant, jakub, marmarek,
	Grzegorz Uriasz, Anthony Perard, j.nowak26, xen-devel


Hi,

This patch series is a small subset of a bigger patch set spanning few projects aiming to isolate the GPU
in QUBES OS to a dedicated security domain. I'm doing this together with 3 colleagues as part of our Bachelors thesis.

When passing an Intel Graphic Device to a HVM guest under XEN, QEMU sometimes crashes
when starting the VM. It turns out that the code responsible for setting up
the legacy VBIOS for the IGD contains a bug which results in a memcpy of an undefined size
between the QEMU heap and the physical memory of the guest.

If the size of the memcpy is small enough qemu does not crash - this means that this
bug is actually a small security issue - a hostile guest kernel might determine the memory layout of
QEMU simply by looking at physical memory beyond 0xdffff - this defeats ASLR and might make exploitation
easier if other issues were to be found.

The problem is the current mechanism for obtaining a copy of the ROM of the IGD.
We first allocate a buffer which holds the vbios - the size of which is obtained from sysfs.
We then try to read the rom from sysfs, if we fail then we just return without setting the size of the buffer.
This would be ok if the size of the ROM reported by sysfs would be 0, but the size is always 32 pages as this corresponds
to legacy memory ranges. It turns out that reading the ROM fails on every single device I've tested(spanning few
generations of IGD), which means qemu never sets the size of the buffer and returns a valid pointer to code which
basically does a memcpy of an undefined size.

I'm including two patches.
The first one fixes the security issue by making failing to read the ROM from sysfs fatal.
The second patch introduces a better method for obtaining the VBIOS. I've haven't yet seen a single device on which
the old code was working, the new code basically creates a shadow copy directly by reading from /dev/mem - this
should be fine as a quick grep of the codebase shows that this approach is already being used to handle MSI.
I've tested the new code on few different laptops and it works fine and the guest VMS finally stopped complaining that
the VBIOS tables are missing.

Grzegorz Uriasz (2):
  Fix undefined behaviour
  Improve legacy vbios handling

 hw/xen/xen_pt.c          |  8 +++++--
 hw/xen/xen_pt_graphics.c | 48 +++++++++++++++++++++++++++++++++++++---
 hw/xen/xen_pt_load_rom.c | 13 +++++------
 3 files changed, 57 insertions(+), 12 deletions(-)

-- 
2.26.1



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

* [PATCH 1/2] Fix undefined behaviour
  2020-04-28  6:28 [PATCH 0/2] Fix QEMU crashes when passing IGD to a guest VM under XEN Grzegorz Uriasz
@ 2020-04-28  6:28 ` Grzegorz Uriasz
  2020-04-28  8:10   ` Paul Durrant
  2020-04-28  8:58   ` Peter Maydell
  2020-04-28  6:28 ` [PATCH 2/2] Improve legacy vbios handling Grzegorz Uriasz
  1 sibling, 2 replies; 8+ messages in thread
From: Grzegorz Uriasz @ 2020-04-28  6:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: artur, Stefano Stabellini, Paul Durrant, jakub, marmarek,
	Grzegorz Uriasz, Anthony Perard, j.nowak26, xen-devel

Signed-off-by: Grzegorz Uriasz <gorbak25@gmail.com>
---
 hw/xen/xen_pt_load_rom.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/hw/xen/xen_pt_load_rom.c b/hw/xen/xen_pt_load_rom.c
index a50a80837e..9f100dc159 100644
--- a/hw/xen/xen_pt_load_rom.c
+++ b/hw/xen/xen_pt_load_rom.c
@@ -38,12 +38,12 @@ void *pci_assign_dev_load_option_rom(PCIDevice *dev,
     fp = fopen(rom_file, "r+");
     if (fp == NULL) {
         if (errno != ENOENT) {
-            error_report("pci-assign: Cannot open %s: %s", rom_file, strerror(errno));
+            warn_report("pci-assign: Cannot open %s: %s", rom_file, strerror(errno));
         }
         return NULL;
     }
     if (fstat(fileno(fp), &st) == -1) {
-        error_report("pci-assign: Cannot stat %s: %s", rom_file, strerror(errno));
+        warn_report("pci-assign: Cannot stat %s: %s", rom_file, strerror(errno));
         goto close_rom;
     }
 
@@ -59,10 +59,9 @@ void *pci_assign_dev_load_option_rom(PCIDevice *dev,
     memset(ptr, 0xff, st.st_size);
 
     if (!fread(ptr, 1, st.st_size, fp)) {
-        error_report("pci-assign: Cannot read from host %s", rom_file);
-        error_printf("Device option ROM contents are probably invalid "
-                     "(check dmesg).\nSkip option ROM probe with rombar=0, "
-                     "or load from file with romfile=\n");
+        warn_report("pci-assign: Cannot read from host %s", rom_file);
+        memory_region_unref(&dev->rom);
+        ptr = NULL;
         goto close_rom;
     }
 
-- 
2.26.1



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

* [PATCH 2/2] Improve legacy vbios handling
  2020-04-28  6:28 [PATCH 0/2] Fix QEMU crashes when passing IGD to a guest VM under XEN Grzegorz Uriasz
  2020-04-28  6:28 ` [PATCH 1/2] Fix undefined behaviour Grzegorz Uriasz
@ 2020-04-28  6:28 ` Grzegorz Uriasz
  1 sibling, 0 replies; 8+ messages in thread
From: Grzegorz Uriasz @ 2020-04-28  6:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: artur, Stefano Stabellini, Paul Durrant, jakub, marmarek,
	Grzegorz Uriasz, Anthony Perard, j.nowak26, xen-devel

Signed-off-by: Grzegorz Uriasz <gorbak25@gmail.com>
---
 hw/xen/xen_pt.c          |  8 +++++--
 hw/xen/xen_pt_graphics.c | 48 +++++++++++++++++++++++++++++++++++++---
 hw/xen/xen_pt_load_rom.c |  2 +-
 3 files changed, 52 insertions(+), 6 deletions(-)

diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index b91082cb8b..ffc3559dd4 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -483,8 +483,12 @@ static int xen_pt_register_regions(XenPCIPassthroughState *s, uint16_t *cmd)
                    i, r->size, r->base_addr, type);
     }
 
-    /* Register expansion ROM address */
-    if (d->rom.base_addr && d->rom.size) {
+    /*
+     * Register expansion ROM address. If we are dealing with a ROM
+     * shadow copy for legacy vga devices then don't bother to map it
+     * as previous code creates a proper shadow copy
+     */
+    if (d->rom.base_addr && d->rom.size && !(is_igd_vga_passthrough(d))) {
         uint32_t bar_data = 0;
 
         /* Re-set BAR reported by OS, otherwise ROM can't be read. */
diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c
index a3bc7e3921..fe0ef2685c 100644
--- a/hw/xen/xen_pt_graphics.c
+++ b/hw/xen/xen_pt_graphics.c
@@ -129,7 +129,7 @@ int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev)
     return 0;
 }
 
-static void *get_vgabios(XenPCIPassthroughState *s, int *size,
+static void *get_sysfs_vgabios(XenPCIPassthroughState *s, int *size,
                        XenHostPCIDevice *dev)
 {
     return pci_assign_dev_load_option_rom(&s->dev, size,
@@ -137,6 +137,45 @@ static void *get_vgabios(XenPCIPassthroughState *s, int *size,
                                           dev->dev, dev->func);
 }
 
+static void xen_pt_direct_vbios_copy(XenPCIPassthroughState *s, Error **errp)
+{
+    int fd = -1;
+    void *guest_bios = NULL;
+    void *host_vbios = NULL;
+    /* This is always 32 pages in the real mode reserved region */
+    int bios_size = 32 << XC_PAGE_SHIFT;
+    int vbios_addr = 0xc0000;
+
+    fd = open("/dev/mem", O_RDONLY);
+    if (fd == -1) {
+        error_setg(errp, "Can't open /dev/mem: %s", strerror(errno));
+        return;
+    }
+    host_vbios = mmap(NULL, bios_size,
+            PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, fd, vbios_addr);
+    close(fd);
+
+    if (host_vbios == MAP_FAILED) {
+        error_setg(errp, "Failed to mmap host vbios: %s", strerror(errno));
+        return;
+    }
+
+    memory_region_init_ram(&s->dev.rom, OBJECT(&s->dev),
+            "legacy_vbios.rom", bios_size, &error_abort);
+    guest_bios = memory_region_get_ram_ptr(&s->dev.rom);
+    memcpy(guest_bios, host_vbios, bios_size);
+
+    if (munmap(host_vbios, bios_size) == -1) {
+        XEN_PT_LOG(&s->dev, "Failed to unmap host vbios: %s\n", strerror(errno));
+    }
+
+    cpu_physical_memory_write(vbios_addr, guest_bios, bios_size);
+    memory_region_set_address(&s->dev.rom, vbios_addr);
+    pci_register_bar(&s->dev, PCI_ROM_SLOT, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->dev.rom);
+    s->dev.has_rom = true;
+    XEN_PT_LOG(&s->dev, "Legacy VBIOS registered\n");
+}
+
 /* Refer to Seabios. */
 struct rom_header {
     uint16_t signature;
@@ -179,9 +218,11 @@ void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev,
         return;
     }
 
-    bios = get_vgabios(s, &bios_size, dev);
+    bios = get_sysfs_vgabios(s, &bios_size, dev);
     if (!bios) {
-        error_setg(errp, "VGA: Can't get VBIOS");
+        XEN_PT_LOG(&s->dev, "Unable to get host VBIOS from sysfs - "
+                            "falling back to a direct copy of memory ranges\n");
+        xen_pt_direct_vbios_copy(s, errp);
         return;
     }
 
@@ -223,6 +264,7 @@ void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev,
 
     /* Currently we fixed this address as a primary for legacy BIOS. */
     cpu_physical_memory_write(0xc0000, bios, bios_size);
+    XEN_PT_LOG(&s->dev, "Legacy VBIOS registered\n");
 }
 
 uint32_t igd_read_opregion(XenPCIPassthroughState *s)
diff --git a/hw/xen/xen_pt_load_rom.c b/hw/xen/xen_pt_load_rom.c
index 9f100dc159..8cd9aa84dc 100644
--- a/hw/xen/xen_pt_load_rom.c
+++ b/hw/xen/xen_pt_load_rom.c
@@ -65,7 +65,7 @@ void *pci_assign_dev_load_option_rom(PCIDevice *dev,
         goto close_rom;
     }
 
-    pci_register_bar(dev, PCI_ROM_SLOT, 0, &dev->rom);
+    pci_register_bar(dev, PCI_ROM_SLOT, PCI_BASE_ADDRESS_SPACE_MEMORY, &dev->rom);
     dev->has_rom = true;
     *size = st.st_size;
 close_rom:
-- 
2.26.1



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

* RE: [PATCH 1/2] Fix undefined behaviour
  2020-04-28  6:28 ` [PATCH 1/2] Fix undefined behaviour Grzegorz Uriasz
@ 2020-04-28  8:10   ` Paul Durrant
  2020-04-28  9:40     ` Artur Puzio
  2020-04-28  8:58   ` Peter Maydell
  1 sibling, 1 reply; 8+ messages in thread
From: Paul Durrant @ 2020-04-28  8:10 UTC (permalink / raw)
  To: 'Grzegorz Uriasz', qemu-devel
  Cc: artur, 'Stefano Stabellini',
	jakub, marmarek, 'Anthony Perard',
	j.nowak26, xen-devel

> -----Original Message-----
> From: Grzegorz Uriasz <gorbak25@gmail.com>
> Sent: 28 April 2020 07:29
> To: qemu-devel@nongnu.org
> Cc: Grzegorz Uriasz <gorbak25@gmail.com>; marmarek@invisiblethingslab.com; artur@puzio.waw.pl;
> jakub@bartmin.ski; j.nowak26@student.uw.edu.pl; Stefano Stabellini <sstabellini@kernel.org>; Anthony
> Perard <anthony.perard@citrix.com>; Paul Durrant <paul@xen.org>; xen-devel@lists.xenproject.org
> Subject: [PATCH 1/2] Fix undefined behaviour
> 
> Signed-off-by: Grzegorz Uriasz <gorbak25@gmail.com>

I think we need more of a commit comment for both this and patch #2 to explain why you are making the changes.

  Paul 



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

* Re: [PATCH 1/2] Fix undefined behaviour
  2020-04-28  6:28 ` [PATCH 1/2] Fix undefined behaviour Grzegorz Uriasz
  2020-04-28  8:10   ` Paul Durrant
@ 2020-04-28  8:58   ` Peter Maydell
  1 sibling, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2020-04-28  8:58 UTC (permalink / raw)
  To: Grzegorz Uriasz
  Cc: artur, Stefano Stabellini, Paul Durrant, jakub, marmarek,
	QEMU Developers, j.nowak26, Anthony Perard, open list:X86

On Tue, 28 Apr 2020 at 08:50, Grzegorz Uriasz <gorbak25@gmail.com> wrote:
>
> Signed-off-by: Grzegorz Uriasz <gorbak25@gmail.com>
> ---
>  hw/xen/xen_pt_load_rom.c | 11 +++++------
>  1 file changed, 5 insertions(+), 6 deletions(-)

The subject doesn't match the patch contents and there is
no long-form part of the commit message explaining why...

thanks
-- PMM


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

* Re: [PATCH 1/2] Fix undefined behaviour
  2020-04-28  8:10   ` Paul Durrant
@ 2020-04-28  9:40     ` Artur Puzio
  2020-04-28 12:32       ` Paul Durrant
  0 siblings, 1 reply; 8+ messages in thread
From: Artur Puzio @ 2020-04-28  9:40 UTC (permalink / raw)
  To: paul, 'Grzegorz Uriasz', qemu-devel
  Cc: 'Stefano Stabellini',
	jakub, marmarek, 'Anthony Perard',
	j.nowak26, xen-devel

On 28.04.2020 10:10, Paul Durrant wrote:
>> -----Original Message-----
>> From: Grzegorz Uriasz <gorbak25@gmail.com>
>> Sent: 28 April 2020 07:29
>> To: qemu-devel@nongnu.org
>> Cc: Grzegorz Uriasz <gorbak25@gmail.com>; marmarek@invisiblethingslab.com; artur@puzio.waw.pl;
>> jakub@bartmin.ski; j.nowak26@student.uw.edu.pl; Stefano Stabellini <sstabellini@kernel.org>; Anthony
>> Perard <anthony.perard@citrix.com>; Paul Durrant <paul@xen.org>; xen-devel@lists.xenproject.org
>> Subject: [PATCH 1/2] Fix undefined behaviour
>>
>> Signed-off-by: Grzegorz Uriasz <gorbak25@gmail.com>
> I think we need more of a commit comment for both this and patch #2 to explain why you are making the changes.
>
>   Paul 

I agree Grzegorz should improve the commit messages. In the mean time
see email with subject "[PATCH 0/2] Fix QEMU crashes when passing IGD to
a guest VM under XEN", it contains quite detailed explanation for both
"Fix undefined behaviour" and "Improve legacy vbios handling" patches.

Artur Puzio



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

* RE: [PATCH 1/2] Fix undefined behaviour
  2020-04-28  9:40     ` Artur Puzio
@ 2020-04-28 12:32       ` Paul Durrant
  2020-04-28 12:33         ` Paul Durrant
  0 siblings, 1 reply; 8+ messages in thread
From: Paul Durrant @ 2020-04-28 12:32 UTC (permalink / raw)
  To: 'Artur Puzio', 'Grzegorz Uriasz', qemu-devel
  Cc: 'Stefano Stabellini',
	jakub, marmarek, 'Anthony Perard',
	j.nowak26, xen-devel

> -----Original Message-----
> From: Artur Puzio <artur@puzio.waw.pl>
> Sent: 28 April 2020 10:41
> To: paul@xen.org; 'Grzegorz Uriasz' <gorbak25@gmail.com>; qemu-devel@nongnu.org
> Cc: marmarek@invisiblethingslab.com; jakub@bartmin.ski; j.nowak26@student.uw.edu.pl; 'Stefano
> Stabellini' <sstabellini@kernel.org>; 'Anthony Perard' <anthony.perard@citrix.com>; xen-
> devel@lists.xenproject.org
> Subject: Re: [PATCH 1/2] Fix undefined behaviour
> 
> On 28.04.2020 10:10, Paul Durrant wrote:
> >> -----Original Message-----
> >> From: Grzegorz Uriasz <gorbak25@gmail.com>
> >> Sent: 28 April 2020 07:29
> >> To: qemu-devel@nongnu.org
> >> Cc: Grzegorz Uriasz <gorbak25@gmail.com>; marmarek@invisiblethingslab.com; artur@puzio.waw.pl;
> >> jakub@bartmin.ski; j.nowak26@student.uw.edu.pl; Stefano Stabellini <sstabellini@kernel.org>;
> Anthony
> >> Perard <anthony.perard@citrix.com>; Paul Durrant <paul@xen.org>; xen-devel@lists.xenproject.org
> >> Subject: [PATCH 1/2] Fix undefined behaviour
> >>
> >> Signed-off-by: Grzegorz Uriasz <gorbak25@gmail.com>
> > I think we need more of a commit comment for both this and patch #2 to explain why you are making
> the changes.
> >
> >   Paul
> 
> I agree Grzegorz should improve the commit messages. In the mean time
> see email with subject "[PATCH 0/2] Fix QEMU crashes when passing IGD to
> a guest VM under XEN", it contains quite detailed explanation for both
> "Fix undefined behaviour" and "Improve legacy vbios handling" patches.
> 

Ok. Can you please make sure maintainers are cc-ed on patch #0 too.

  Paul



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

* RE: [PATCH 1/2] Fix undefined behaviour
  2020-04-28 12:32       ` Paul Durrant
@ 2020-04-28 12:33         ` Paul Durrant
  0 siblings, 0 replies; 8+ messages in thread
From: Paul Durrant @ 2020-04-28 12:33 UTC (permalink / raw)
  To: paul, 'Artur Puzio', 'Grzegorz Uriasz', qemu-devel
  Cc: 'Stefano Stabellini',
	jakub, marmarek, 'Anthony Perard',
	j.nowak26, xen-devel

> -----Original Message-----
> From: Paul Durrant <xadimgnik@gmail.com>
> Sent: 28 April 2020 13:33
> To: 'Artur Puzio' <artur@puzio.waw.pl>; 'Grzegorz Uriasz' <gorbak25@gmail.com>; qemu-devel@nongnu.org
> Cc: marmarek@invisiblethingslab.com; jakub@bartmin.ski; j.nowak26@student.uw.edu.pl; 'Stefano
> Stabellini' <sstabellini@kernel.org>; 'Anthony Perard' <anthony.perard@citrix.com>; xen-
> devel@lists.xenproject.org
> Subject: RE: [PATCH 1/2] Fix undefined behaviour
> 
> > -----Original Message-----
> > From: Artur Puzio <artur@puzio.waw.pl>
> > Sent: 28 April 2020 10:41
> > To: paul@xen.org; 'Grzegorz Uriasz' <gorbak25@gmail.com>; qemu-devel@nongnu.org
> > Cc: marmarek@invisiblethingslab.com; jakub@bartmin.ski; j.nowak26@student.uw.edu.pl; 'Stefano
> > Stabellini' <sstabellini@kernel.org>; 'Anthony Perard' <anthony.perard@citrix.com>; xen-
> > devel@lists.xenproject.org
> > Subject: Re: [PATCH 1/2] Fix undefined behaviour
> >
> > On 28.04.2020 10:10, Paul Durrant wrote:
> > >> -----Original Message-----
> > >> From: Grzegorz Uriasz <gorbak25@gmail.com>
> > >> Sent: 28 April 2020 07:29
> > >> To: qemu-devel@nongnu.org
> > >> Cc: Grzegorz Uriasz <gorbak25@gmail.com>; marmarek@invisiblethingslab.com; artur@puzio.waw.pl;
> > >> jakub@bartmin.ski; j.nowak26@student.uw.edu.pl; Stefano Stabellini <sstabellini@kernel.org>;
> > Anthony
> > >> Perard <anthony.perard@citrix.com>; Paul Durrant <paul@xen.org>; xen-devel@lists.xenproject.org
> > >> Subject: [PATCH 1/2] Fix undefined behaviour
> > >>
> > >> Signed-off-by: Grzegorz Uriasz <gorbak25@gmail.com>
> > > I think we need more of a commit comment for both this and patch #2 to explain why you are making
> > the changes.
> > >
> > >   Paul
> >
> > I agree Grzegorz should improve the commit messages. In the mean time
> > see email with subject "[PATCH 0/2] Fix QEMU crashes when passing IGD to
> > a guest VM under XEN", it contains quite detailed explanation for both
> > "Fix undefined behaviour" and "Improve legacy vbios handling" patches.
> >
> 
> Ok. Can you please make sure maintainers are cc-ed on patch #0 too.
> 

Actually they are, sorry. My MUA is playing tricks on me.

  Paul



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

end of thread, other threads:[~2020-04-28 12:33 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-28  6:28 [PATCH 0/2] Fix QEMU crashes when passing IGD to a guest VM under XEN Grzegorz Uriasz
2020-04-28  6:28 ` [PATCH 1/2] Fix undefined behaviour Grzegorz Uriasz
2020-04-28  8:10   ` Paul Durrant
2020-04-28  9:40     ` Artur Puzio
2020-04-28 12:32       ` Paul Durrant
2020-04-28 12:33         ` Paul Durrant
2020-04-28  8:58   ` Peter Maydell
2020-04-28  6:28 ` [PATCH 2/2] Improve legacy vbios handling Grzegorz Uriasz

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).