> 20.05.2011 21:33, Moritz Muehlenhoff wrote:
>> Package: qemu-kvm
>> Severity: grave
>> Tags: security
>>
>> Hi,
>> the following security issue was reported in qemu-kvm:
>>
>> CVE-2011-1751:
>> http://lists.nongnu.org/archive/html/qemu-devel/2011-05/msg01810.html
>> http://patchwork.ozlabs.org/patch/96331/

Ok, the upstream patch is simple and trivial but it requires
some infrastructure changes which went into qemu after 0.12
version and hence is not present in the version currently
in Squeeze.

I did some backporting work for the minimal set of changes
necessary for this fix to work.  There are 5 preparational
patches in total, plus the actual fix for CVE-2011-1751.
Attached is a debdiff for the whole thing, which has some
details about the applied patches in the debian/changelog.
Here are some more details.

o background.  The problem at hand is that it is possible
  from a virtual machine to request a hot-unplug of certain
  devices which has never been hot-unpluggable to start with,
  but qemu (and qemu-kvm) does not check this, and due to
  lack of proper unplug routines for, say, ISA brige or
  ACPI devices, qemu merely frees the device structures.
  But the devices aren't unpluggable and other parts of
  qemu continue referring to them, leading to havoc which
  can be abused to do evil things.

o the upstream fix is really simple: it merely checks
  no_hotplug property before actually freeing the device
  structures.

o but the problem is that 0.12 does not have that property
  yet, it has been introduced later.

o so the main backported change was to introduce that property
  and mark all required devices as non-hotpluggable.  This
  part was rather trivial too.

o the main questionable change is hotplug-0-acpi_piix4-qdevfy-e8ec0571e1.diff,
  which is a backport of an upstream change (all patches are
  actually backports from upstream) for a subdevice of piix4,
  which implements its conversion into qdev infrastructure
  (this is a "new" device model in qemu introduced before
  0.12 but not all devices are converted to it).  The backport
  went rather ugly, since the code around changed somewhat in
  upstream.

o and finally, there was one more change needed for the main
  infrastructure patch (which invents no_hotplug attribute),
  this is a cleanup (and bugfix) patch that refactors an
  error-cleanup code into a separate function and this function
  gets called from one more place.  Main infrastructure change
  calls it too when discovering it's trying to hot-plug a
  non-hotpluggable device.

So the most problematic change is acpi_piix4-qdevfy, all the
rest are rather simple and obvious and does not lead to any
significant behavour changes - whole thing merely disallows
operations which makes no sense to begin with, now with
proper error messages.

I verified that the software works as expected after the changes,
trying several different guests.  Also, I discovered that RHEL6.1
contains very similar backports of all patches I backported, plus
quite alot more - ie, they went further than just fixing the issue,
in qemu-kvm-0.12.1.2-2.160.el6 - fwiw.

I want to get additional upstream confirmation about correctness
of the backports I made, because I'm not really familiar with this
part of the codebase.  Hopefully I can get something at Monday.
Meanwile I'm asking the security team for whole thing - let's
assume the changes are actually ok - is the diff this large ok
for -security?

Because if it is not, there's one other possible way to fix this,
but it's ugly and hackish.  I mean, I can just compare the
device being unplugged against a set of device descriptors
defined statically in several files, removing "static" attributes
from all the places.  This surely will work as expected, without
risking to introduce breakage, but it is too ugly for my taste.

Thank you for attention.

/mjt
diff -u qemu-kvm-0.12.5+dfsg/debian/changelog 
qemu-kvm-0.12.5+dfsg/debian/changelog
--- qemu-kvm-0.12.5+dfsg/debian/changelog
+++ qemu-kvm-0.12.5+dfsg/debian/changelog
@@ -1,3 +1,27 @@
+qemu-kvm (0.12.5+dfsg-5+squeeze2) stable-security; urgency=high
+
+  * fix CVE-2011-1751 for 0.12.  The actual fix is in
+    hotplug-4-ignore-pci-hotplug-requests-for-unpluggable-devices-CVE-2011-1751
+    but that change, while trivial, required 6 more changes to be backported
+    to 0.12:
+   o pci-cleanly-backout-of-pci_qdev_init-925fe64ae7
+      (moving common code to a separate function and using it from another
+      place to fix a memory leak)
+   o hotplug-0-acpi_piix4-qdevfy-e8ec0571e1
+      this qdevifies acpi_piix4 device
+   o hotplug-1-pci-allow-devices-being-tagged-as-not-hotpluggable-180c22e18b
+      introduce a "no_hotplug" attribute and check it in common places
+      to ensure such devices wont be hot-(un)plugged.  This needs
+      the pci-cleanly-backout-of-pci_qdev_init patch mentioned above
+   o hotplug-2-piix-tag-as-not-hotpluggable-0965f12da6
+   o hotplug-3-vga-tag-as-not-hotplugable-be92bbf73d
+      mark certain devices as non-hotpluggable
+    And finally the actual fix for CVE-2011-1751, which verifies the
+    no_hotplug attribute when handling hot-unplug request from guest.
+    (closes: #627448)
+
+ -- Michael Tokarev <m...@tls.msk.ru>  Sat, 21 May 2011 10:45:52 +0400
+
 qemu-kvm (0.12.5+dfsg-5+squeeze1) stable-security; urgency=high
 
   * fix CVE-2011-0011: Setting VNC password to empty string
@@ -6,7 +30,7 @@
      by unaligned requests (Closes: #624177)
   * urgency is high due to #624177
 
- -- Michael Tokarev <m...@tls.msk.ru>  Tue, 26 Apr 2011 12:04:36 +0400
+ -- Michael Tokarev <m...@tls.msk.ru>  Sat, 21 May 2011 10:45:03 +0400
 
 qemu-kvm (0.12.5+dfsg-5) unstable; urgency=low
 
diff -u qemu-kvm-0.12.5+dfsg/debian/patches/series 
qemu-kvm-0.12.5+dfsg/debian/patches/series
--- qemu-kvm-0.12.5+dfsg/debian/patches/series
+++ qemu-kvm-0.12.5+dfsg/debian/patches/series
@@ -31,0 +32,9 @@
+
+# no_hotplug & pci infrastructure preparation for CVE-2011-1751 fix
+pci-cleanly-backout-of-pci_qdev_init-925fe64ae7.diff
+hotplug-0-acpi_piix4-qdevfy-e8ec0571e1.diff
+hotplug-1-pci-allow-devices-being-tagged-as-not-hotpluggable-180c22e18b.diff
+hotplug-2-piix-tag-as-not-hotpluggable-0965f12da6.diff
+hotplug-3-vga-tag-as-not-hotplugable-be92bbf73d.diff
+# this is the main patch to actually fix CVE-2011-1751
+hotplug-4-ignore-pci-hotplug-requests-for-unpluggable-devices-CVE-2011-1751.diff
only in patch2:
unchanged:
--- 
qemu-kvm-0.12.5+dfsg.orig/debian/patches/pci-cleanly-backout-of-pci_qdev_init-925fe64ae7.diff
+++ 
qemu-kvm-0.12.5+dfsg/debian/patches/pci-cleanly-backout-of-pci_qdev_init-925fe64ae7.diff
@@ -0,0 +1,57 @@
+commit 925fe64ae7b487fdb7bd56fcab63e2f87653c226
+Author: Alex Williamson <alex.william...@redhat.com>
+Date:   Tue May 11 06:44:21 2010 -0400
+
+    pci: cleanly backout of pci_qdev_init()
+    
+    If the init function of a device fails, as might happen with device
+    assignment, we never undo the work done by do_pci_register_device().
+    This not only causes a bit of a memory leak, but also leaves a bogus
+    pointer in the bus devices array that can cause a segfault or
+    garbage data from 'info pci'.
+    
+    Signed-off-by: Alex Williamson <alex.william...@redhat.com>
+    Signed-off-by: Michael S. Tsirkin <m...@redhat.com>
+
+diff --git a/hw/pci.c b/hw/pci.c
+index f167436..3ca5f09 100644
+--- a/hw/pci.c
++++ b/hw/pci.c
+@@ -625,6 +625,13 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev, PCIBus *bus,
+     return pci_dev;
+ }
+ 
++static void do_pci_unregister_device(PCIDevice *pci_dev)
++{
++    qemu_free_irqs(pci_dev->irq);
++    pci_dev->bus->devices[pci_dev->devfn] = NULL;
++    pci_config_free(pci_dev);
++}
++
+ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
+                                int instance_size, int devfn,
+                                PCIConfigReadFunc *config_read,
+@@ -680,10 +687,7 @@ static int pci_unregister_device(DeviceState *dev)
+         return ret;
+ 
+     pci_unregister_io_regions(pci_dev);
+-
+-    qemu_free_irqs(pci_dev->irq);
+-    pci_dev->bus->devices[pci_dev->devfn] = NULL;
+-    pci_config_free(pci_dev);
++    do_pci_unregister_device(pci_dev);
+     return 0;
+ }
+ 
+@@ -1652,8 +1656,10 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo 
*base)
+     if (pci_dev == NULL)
+         return -1;
+     rc = info->init(pci_dev);
+-    if (rc != 0)
++    if (rc != 0) {
++        do_pci_unregister_device(pci_dev);
+         return rc;
++    }
+ 
+     /* rom loading */
+     if (pci_dev->romfile == NULL && info->romfile != NULL)
only in patch2:
unchanged:
--- 
qemu-kvm-0.12.5+dfsg.orig/debian/patches/hotplug-3-vga-tag-as-not-hotplugable-be92bbf73d.diff
+++ 
qemu-kvm-0.12.5+dfsg/debian/patches/hotplug-3-vga-tag-as-not-hotplugable-be92bbf73d.diff
@@ -0,0 +1,47 @@
+Refreshed line offsets from upstream patch.
+       -- mjt
+
+commit be92bbf73dfd7d8a4786dc5f6c71590f4fbc5a32
+Author: Gerd Hoffmann <kra...@redhat.com>
+Date:   Thu Jan 6 15:14:39 2011 +0100
+
+    vga: tag as not hotplugable.
+    
+    This patch tags all vga cards as not hotpluggable.  The qemu
+    standard vga will never ever be hotpluggable.  For cirrus + vmware
+    it might be possible to get that work some day.  Todays we can't
+    handle that for a number of reasons though.
+    
+    Signed-off-by: Gerd Hoffmann <kra...@redhat.com>
+    Signed-off-by: Michael S. Tsirkin <m...@redhat.com>
+
+--- debian.orig/hw/cirrus_vga.c        2011-05-21 10:38:06.988265846 +0400
++++ debian/hw/cirrus_vga.c     2011-05-21 16:01:28.411180032 +0400
+@@ -3241,6 +3241,7 @@ static PCIDeviceInfo cirrus_vga_info = {
+     .qdev.desc    = "Cirrus CLGD 54xx VGA",
+     .qdev.size    = sizeof(PCICirrusVGAState),
+     .qdev.vmsd    = &vmstate_pci_cirrus_vga,
++    .no_hotplug   = 1,
+     .init         = pci_cirrus_vga_initfn,
+     .romfile      = VGABIOS_CIRRUS_FILENAME,
+     .config_write = pci_cirrus_write_config,
+--- debian.orig/hw/vga-pci.c   2011-04-26 08:53:39.000000000 +0400
++++ debian/hw/vga-pci.c        2011-05-21 16:01:28.411180032 +0400
+@@ -131,6 +131,7 @@ static PCIDeviceInfo vga_info = {
+     .qdev.name    = "VGA",
+     .qdev.size    = sizeof(PCIVGAState),
+     .qdev.vmsd    = &vmstate_vga_pci,
++    .no_hotplug   = 1,
+     .init         = pci_vga_initfn,
+     .config_write = pci_vga_write_config,
+     .qdev.props   = (Property[]) {
+--- debian.orig/hw/vmware_vga.c        2011-04-26 08:53:39.000000000 +0400
++++ debian/hw/vmware_vga.c     2011-05-21 16:01:28.411180032 +0400
+@@ -1243,6 +1243,7 @@ static PCIDeviceInfo vmsvga_info = {
+     .qdev.name    = "vmware-svga",
+     .qdev.size    = sizeof(struct pci_vmsvga_state_s),
+     .qdev.vmsd    = &vmstate_vmware_vga,
++    .no_hotplug   = 1,
+     .init         = pci_vmsvga_initfn,
+ };
+ 
only in patch2:
unchanged:
--- 
qemu-kvm-0.12.5+dfsg.orig/debian/patches/hotplug-0-acpi_piix4-qdevfy-e8ec0571e1.diff
+++ 
qemu-kvm-0.12.5+dfsg/debian/patches/hotplug-0-acpi_piix4-qdevfy-e8ec0571e1.diff
@@ -0,0 +1,110 @@
+Backported upstream commit.  Quite some stuff changed
+in upstream since 0.12.  -- mjt
+
+commit e8ec0571e16115203f4d6cc7eb31f930167592f8
+Author: Isaku Yamahata <yamah...@valinux.co.jp>
+Date:   Fri May 14 16:29:18 2010 +0900
+
+    acpi_piix4: qdevfy.
+    
+    qdevfy acpi_piix4.
+    
+    Signed-off-by: Isaku Yamahata <yamah...@valinux.co.jp>
+    Acked-by: Gerd Hoffmann <kra...@redhat.com>
+    Signed-off-by: Blue Swirl <blauwir...@gmail.com>
+
+--- debian.orig/hw/acpi.c      2011-05-21 14:18:02.000000000 +0400
++++ debian/hw/acpi.c   2011-05-21 15:42:37.030310762 +0400
+@@ -43,6 +43,7 @@ typedef struct PIIX4PMState {
+     QEMUTimer *tmr_timer;
+     int64_t tmr_overflow_time;
+     i2c_bus *smbus;
++    uint32_t smb_io_base;
+     uint8_t smb_stat;
+     uint8_t smb_ctl;
+     uint8_t smb_cmd;
+@@ -500,15 +501,11 @@ static void piix4_powerdown(void *opaque
+ #endif
+ }
+ 
+-i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
+-                       qemu_irq sci_irq)
++static int piix4_pm_initfn(PCIDevice *dev)
+ {
+-    PIIX4PMState *s;
++    PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev, dev);
+     uint8_t *pci_conf;
+ 
+-    s = (PIIX4PMState *)pci_register_device(bus,
+-                                         "PM", sizeof(PIIX4PMState),
+-                                         devfn, NULL, pm_write_config);
+     pm_state = s;
+     pci_conf = s->dev.config;
+     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
+@@ -548,25 +545,59 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int
+     pci_conf[0x67] = (serial_hds[0] != NULL ? 0x08 : 0) |
+       (serial_hds[1] != NULL ? 0x90 : 0);
+ 
+-    pci_conf[0x90] = smb_io_base | 1;
+-    pci_conf[0x91] = smb_io_base >> 8;
++    pci_conf[0x90] = s->smb_io_base | 1;
++    pci_conf[0x91] = s->smb_io_base >> 8;
+     pci_conf[0xd2] = 0x09;
+-    register_ioport_write(smb_io_base, 64, 1, smb_ioport_writeb, s);
+-    register_ioport_read(smb_io_base, 64, 1, smb_ioport_readb, s);
++    register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, s);
++    register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, s);
+ 
+     s->tmr_timer = qemu_new_timer(vm_clock, pm_tmr_timer, s);
+ 
+     qemu_system_powerdown = *qemu_allocate_irqs(piix4_powerdown, s, 1);
+ 
+-    vmstate_register(0, &vmstate_acpi, s);
+-
+     s->smbus = i2c_init_bus(NULL, "i2c");
+-    s->irq = sci_irq;
+     qemu_register_reset(piix4_reset, s);
+ 
++    return 0;
++}
++
++i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
++                       qemu_irq sci_irq)
++{
++    PCIDevice *dev;
++    PIIX4PMState *s;
++
++    dev = pci_create(bus, devfn, "PIIX4_PM");
++    qdev_prop_set_uint32(&dev->qdev, "smb_io_base", smb_io_base);
++
++    s = DO_UPCAST(PIIX4PMState, dev, dev);
++    s->irq = sci_irq;
++
++    qdev_init_nofail(&dev->qdev);
++
+     return s->smbus;
+ }
+ 
++static PCIDeviceInfo piix4_pm_info = {
++    .qdev.name          = "PIIX4_PM",
++    .qdev.desc          = "PM",
++    .qdev.size          = sizeof(PIIX4PMState),
++    .qdev.vmsd          = &vmstate_acpi,
++    .init               = piix4_pm_initfn,
++    .config_write       = pm_write_config,
++    .qdev.props         = (Property[]) {
++        DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
++        DEFINE_PROP_END_OF_LIST(),
++    }
++};
++
++static void piix4_pm_register(void)
++{
++    pci_qdev_register(&piix4_pm_info);
++}
++
++device_init(piix4_pm_register);
++
+ #define GPE_BASE 0xafe0
+ #define PROC_BASE 0xaf00
+ #define PCI_BASE 0xae00
only in patch2:
unchanged:
--- 
qemu-kvm-0.12.5+dfsg.orig/debian/patches/hotplug-2-piix-tag-as-not-hotpluggable-0965f12da6.diff
+++ 
qemu-kvm-0.12.5+dfsg/debian/patches/hotplug-2-piix-tag-as-not-hotpluggable-0965f12da6.diff
@@ -0,0 +1,71 @@
+Trivial backport from upstream (file name change, refreshed offsets)
+       -- mjt
+
+commit 0965f12da61cbfe62252d21a8e6fa309753760e8
+Author: Gerd Hoffmann <kra...@redhat.com>
+Date:   Thu Jan 6 15:14:38 2011 +0100
+
+    piix: tag as not hotpluggable.
+    
+    This patch tags all pci devices which belong to the piix3/4 chipsets as
+    not hotpluggable (Host bridge, ISA bridge, IDE controller, ACPI bridge).
+    
+    Acked-by: Aurelien Jarno <aurel...@aurel32.net>
+    Signed-off-by: Gerd Hoffmann <kra...@redhat.com>
+    Signed-off-by: Michael S. Tsirkin <m...@redhat.com>
+
+--- debian.orig/hw/acpi.c      2011-05-21 15:42:37.030310762 +0400
++++ debian/hw/acpi.c   2011-05-21 16:00:52.903435908 +0400
+@@ -583,6 +583,8 @@ static PCIDeviceInfo piix4_pm_info = {
+     .qdev.desc          = "PM",
+     .qdev.size          = sizeof(PIIX4PMState),
+     .qdev.vmsd          = &vmstate_acpi,
++    .qdev.no_user       = 1,
++    .no_hotplug         = 1,
+     .init               = piix4_pm_initfn,
+     .config_write       = pm_write_config,
+     .qdev.props         = (Property[]) {
+--- debian.orig/hw/ide/piix.c  2011-05-21 10:38:07.000000000 +0400
++++ debian/hw/ide/piix.c       2011-05-21 16:00:52.903435908 +0400
+@@ -183,11 +183,13 @@ static PCIDeviceInfo piix_ide_info[] = {
+         .qdev.name    = "piix3-ide",
+         .qdev.size    = sizeof(PCIIDEState),
+         .qdev.no_user = 1,
++        .no_hotplug   = 1,
+         .init         = pci_piix3_ide_initfn,
+     },{
+         .qdev.name    = "piix4-ide",
+         .qdev.size    = sizeof(PCIIDEState),
+         .qdev.no_user = 1,
++        .no_hotplug   = 1,
+         .init         = pci_piix4_ide_initfn,
+     },{
+         /* end of list */
+--- debian.orig/hw/piix4.c     2011-04-26 08:53:39.000000000 +0400
++++ debian/hw/piix4.c  2011-05-21 16:00:52.903435908 +0400
+@@ -115,6 +115,7 @@ static PCIDeviceInfo piix4_info[] = {
+         .qdev.desc    = "ISA bridge",
+         .qdev.size    = sizeof(PCIDevice),
+         .qdev.no_user = 1,
++        .no_hotplug   = 1,
+         .init         = piix4_initfn,
+     },{
+         /* end of list */
+--- debian.orig/hw/piix_pci.c  2011-04-26 08:53:39.000000000 +0400
++++ debian/hw/piix_pci.c       2011-05-21 16:00:52.906770908 +0400
+@@ -347,6 +347,7 @@ static PCIDeviceInfo i440fx_info[] = {
+         .qdev.size    = sizeof(PCII440FXState),
+         .qdev.vmsd    = &vmstate_i440fx,
+         .qdev.no_user = 1,
++        .no_hotplug   = 1,
+         .init         = i440fx_initfn,
+         .config_write = i440fx_write_config,
+     },{
+@@ -355,6 +356,7 @@ static PCIDeviceInfo i440fx_info[] = {
+         .qdev.size    = sizeof(PIIX3State),
+         .qdev.vmsd    = &vmstate_piix3,
+         .qdev.no_user = 1,
++        .no_hotplug   = 1,
+         .init         = piix3_initfn,
+     },{
+         /* end of list */
only in patch2:
unchanged:
--- 
qemu-kvm-0.12.5+dfsg.orig/debian/patches/hotplug-1-pci-allow-devices-being-tagged-as-not-hotpluggable-180c22e18b.diff
+++ 
qemu-kvm-0.12.5+dfsg/debian/patches/hotplug-1-pci-allow-devices-being-tagged-as-not-hotpluggable-180c22e18b.diff
@@ -0,0 +1,78 @@
+Backported from upstream.  qerror.[ch] trivial changes.
+       -- mjt
+
+commit 180c22e18b0a9be21445271f94347238b0bc0a25
+Author: Gerd Hoffmann <kra...@redhat.com>
+Date:   Thu Jan 6 15:14:37 2011 +0100
+
+    pci: allow devices being tagged as not hotpluggable.
+    
+    This patch adds a field to PCIDeviceInfo to tag devices as being
+    not hotpluggable.  Any attempt to plug-in or -out such a device
+    will throw an error.
+    
+    Signed-off-by: Gerd Hoffmann <kra...@redhat.com>
+    Signed-off-by: Michael S. Tsirkin <m...@redhat.com>
+
+--- debian.orig/hw/pci.c       2011-04-26 08:53:39.000000000 +0400
++++ debian/hw/pci.c    2011-05-21 15:52:55.354792693 +0400
+@@ -1479,6 +1479,11 @@ static int pci_qdev_init(DeviceState *qd
+                                      info->header_type);
+     if (pci_dev == NULL)
+         return -1;
++    if (qdev->hotplugged && info->no_hotplug) {
++        qemu_error_new(QERR_DEVICE_NO_HOTPLUG, info->qdev.name);
++        do_pci_unregister_device(pci_dev);
++        return -1;
++    }
+     rc = info->init(pci_dev);
+     if (rc != 0)
+         return rc;
+@@ -1496,6 +1501,12 @@ static int pci_qdev_init(DeviceState *qd
+ static int pci_unplug_device(DeviceState *qdev)
+ {
+     PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);
++    PCIDeviceInfo *info = container_of(qdev->info, PCIDeviceInfo, qdev);
++
++    if (info->no_hotplug) {
++        qemu_error_new(QERR_DEVICE_NO_HOTPLUG, info->qdev.name);
++        return -1;
++    }
+ 
+     dev->bus->hotplug(dev, 0);
+     return 0;
+--- debian.orig/hw/pci.h       2011-04-26 08:53:39.000000000 +0400
++++ debian/hw/pci.h    2011-05-21 15:49:59.167925019 +0400
+@@ -443,6 +443,9 @@ typedef struct {
+     /* pcie stuff */
+     int is_express;   /* is this device pci express? */
+ 
++    /* device isn't hot-pluggable */
++    int no_hotplug;
++
+     /* rom bar */
+     const char *romfile;
+ } PCIDeviceInfo;
+--- debian.orig/qerror.c       2011-04-26 08:53:39.000000000 +0400
++++ debian/qerror.c    2011-05-21 15:57:06.957191482 +0400
+@@ -120,6 +120,10 @@ static const QErrorStringTable qerror_ta
+         .error_fmt = QERR_VNC_SERVER_FAILED,
+         .desc      = "Could not start VNC server on %(target)",
+     },
++    {
++        .error_fmt = QERR_DEVICE_NO_HOTPLUG,
++        .desc      = "Device '%(device)' does not support hotplugging",
++    },
+     {}
+ };
+ 
+--- debian.orig/qerror.h       2011-04-26 08:53:39.000000000 +0400
++++ debian/qerror.h    2011-05-21 15:57:51.195965390 +0400
+@@ -100,4 +100,7 @@ QError *qobject_to_qerror(const QObject
+ #define QERR_VNC_SERVER_FAILED \
+     "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }"
+ 
++#define QERR_DEVICE_NO_HOTPLUG \
++    "{ 'class': 'DeviceNoHotplug', 'data': { 'device': %s } }"
++
+ #endif /* QERROR_H */
only in patch2:
unchanged:
--- 
qemu-kvm-0.12.5+dfsg.orig/debian/patches/hotplug-4-ignore-pci-hotplug-requests-for-unpluggable-devices-CVE-2011-1751.diff
+++ 
qemu-kvm-0.12.5+dfsg/debian/patches/hotplug-4-ignore-pci-hotplug-requests-for-unpluggable-devices-CVE-2011-1751.diff
@@ -0,0 +1,45 @@
+Refreshed for 0.12 - the code moved from hw/acpi.c to hw/acpi_piix4.c
+in upstream version.
+                       -- mjt
+
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: Ignore pci unplug requests for unpluggable devices (CVE-2011-1751)
+Date: Wed, 18 May 2011 23:13:13 -0000
+From: Gerd Hoffmann <kra...@redhat.com>
+X-Patchwork-Id: 96331
+Message-Id: <1305796393-22786-2-git-send-email-kra...@redhat.com>
+To: qemu-de...@nongnu.org
+Cc: Gerd Hoffmann <kra...@redhat.com>
+
+This patch makes qemu ignore unplug requests from the guest for pci
+devices which are tagged as non-hotpluggable.  Trouble spot is the
+piix4 chipset with the ISA bridge.  Requests to unplug that one will
+make it go away together with all ISA bus devices, which are not
+prepared to be unplugged and thus don't cleanup, leaving active
+qemu timers behind in free'ed memory.
+
+Signed-off-by: Gerd Hoffmann <kra...@redhat.com>
+
+---
+hw/acpi_piix4.c |    4 +++-
+ 1 files changed, 3 insertions(+), 1 deletions(-)
+
+--- debian.orig/hw/acpi.c      2011-05-21 16:00:52.903435908 +0400
++++ debian/hw/acpi.c   2011-05-21 16:02:18.359473876 +0400
+@@ -749,11 +749,13 @@ static void pciej_write(void *opaque, ui
+     BusState *bus = opaque;
+     DeviceState *qdev, *next;
+     PCIDevice *dev;
++    PCIDeviceInfo *info;
+     int slot = ffs(val) - 1;
+ 
+     QLIST_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
+         dev = DO_UPCAST(PCIDevice, qdev, qdev);
+-        if (PCI_SLOT(dev->devfn) == slot) {
++        info = container_of(qdev->info, PCIDeviceInfo, qdev);
++        if (PCI_SLOT(dev->devfn) == slot && !info->no_hotplug) {
+             qdev_free(qdev);
+         }
+     }

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to