CVE-2016-3710: incorrect bounds checking in vga (bz #1334345)

CVE-2016-3712: out of bounds read in vga (bz #1334342)
Fix USB redirection (bz #1330221)
CVE-2016-4037: infinite loop in usb ehci (bz #1328080)
CVE-2016-4001: buffer overflow in stellaris net (bz #1325885)
CVE-2016-2858: rng stack corruption (bz #1314677)
CVE-2016-2391: ohci: crash via multiple timers (bz #1308881)
CVE-2016-2198: ehci: null pointer dereference (bz #1303134)
Fix ./configure with ccache
This commit is contained in:
Cole Robinson 2016-05-09 20:08:58 -04:00
parent d62b5c0e5f
commit 44ee7cd460
17 changed files with 1343 additions and 1 deletions

View File

@ -0,0 +1,104 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 26 Apr 2016 08:49:10 +0200
Subject: [PATCH] vga: fix banked access bounds checking (CVE-2016-3710)
vga allows banked access to video memory using the window at 0xa00000
and it supports a different access modes with different address
calculations.
The VBE bochs extentions support banked access too, using the
VBE_DISPI_INDEX_BANK register. The code tries to take the different
address calculations into account and applies different limits to
VBE_DISPI_INDEX_BANK depending on the current access mode.
Which is probably effective in stopping misprogramming by accident.
But from a security point of view completely useless as an attacker
can easily change access modes after setting the bank register.
Drop the bogus check, add range checks to vga_mem_{readb,writeb}
instead.
Fixes: CVE-2016-3710
Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 3bf1817079bb0d80c0d8a86a7c7dd0bfe90eb82e)
---
hw/display/vga.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/hw/display/vga.c b/hw/display/vga.c
index d1d296c..a26c8f4 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -177,6 +177,7 @@ static void vga_update_memory_access(VGACommonState *s)
size = 0x8000;
break;
}
+ assert(offset + size <= s->vram_size);
memory_region_init_alias(&s->chain4_alias, memory_region_owner(&s->vram),
"vga.chain4", &s->vram, offset, size);
memory_region_add_subregion_overlap(s->legacy_address_space, base,
@@ -714,11 +715,7 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
vbe_fixup_regs(s);
break;
case VBE_DISPI_INDEX_BANK:
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
- val &= (s->vbe_bank_mask >> 2);
- } else {
- val &= s->vbe_bank_mask;
- }
+ val &= s->vbe_bank_mask;
s->vbe_regs[s->vbe_index] = val;
s->bank_offset = (val << 16);
vga_update_memory_access(s);
@@ -817,13 +814,21 @@ uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr)
if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
/* chain 4 mode : simplest access */
+ assert(addr < s->vram_size);
ret = s->vram_ptr[addr];
} else if (s->gr[VGA_GFX_MODE] & 0x10) {
/* odd/even mode (aka text mode mapping) */
plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
- ret = s->vram_ptr[((addr & ~1) << 1) | plane];
+ addr = ((addr & ~1) << 1) | plane;
+ if (addr >= s->vram_size) {
+ return 0xff;
+ }
+ ret = s->vram_ptr[addr];
} else {
/* standard VGA latched access */
+ if (addr * sizeof(uint32_t) >= s->vram_size) {
+ return 0xff;
+ }
s->latch = ((uint32_t *)s->vram_ptr)[addr];
if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
@@ -880,6 +885,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
plane = addr & 3;
mask = (1 << plane);
if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
+ assert(addr < s->vram_size);
s->vram_ptr[addr] = val;
#ifdef DEBUG_VGA_MEM
printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
@@ -893,6 +899,9 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
mask = (1 << plane);
if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
addr = ((addr & ~1) << 1) | plane;
+ if (addr >= s->vram_size) {
+ return;
+ }
s->vram_ptr[addr] = val;
#ifdef DEBUG_VGA_MEM
printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
@@ -966,6 +975,9 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
mask = s->sr[VGA_SEQ_PLANE_WRITE];
s->plane_updated |= mask; /* only used to detect font change */
write_mask = mask16[mask];
+ if (addr * sizeof(uint32_t) >= s->vram_size) {
+ return;
+ }
((uint32_t *)s->vram_ptr)[addr] =
(((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
(val & write_mask);

View File

@ -0,0 +1,64 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 26 Apr 2016 14:11:34 +0200
Subject: [PATCH] vga: add vbe_enabled() helper
Makes code a bit easier to read.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit bfa0f151a564a83b5a26f3e917da98674bf3cf62)
---
hw/display/vga.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/hw/display/vga.c b/hw/display/vga.c
index a26c8f4..955ad6f 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -140,6 +140,11 @@ static uint32_t expand4[256];
static uint16_t expand2[256];
static uint8_t expand4to8[16];
+static inline bool vbe_enabled(VGACommonState *s)
+{
+ return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED;
+}
+
static void vga_update_memory_access(VGACommonState *s)
{
hwaddr base, offset, size;
@@ -562,7 +567,7 @@ static void vbe_fixup_regs(VGACommonState *s)
uint16_t *r = s->vbe_regs;
uint32_t bits, linelength, maxy, offset;
- if (!(r[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
+ if (!vbe_enabled(s)) {
/* vbe is turned off -- nothing to do */
return;
}
@@ -1056,7 +1061,7 @@ static void vga_get_offsets(VGACommonState *s,
{
uint32_t start_addr, line_offset, line_compare;
- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
+ if (vbe_enabled(s)) {
line_offset = s->vbe_line_offset;
start_addr = s->vbe_start_addr;
line_compare = 65535;
@@ -1381,7 +1386,7 @@ static int vga_get_bpp(VGACommonState *s)
{
int ret;
- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
+ if (vbe_enabled(s)) {
ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
} else {
ret = 0;
@@ -1393,7 +1398,7 @@ static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
{
int width, height;
- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
+ if (vbe_enabled(s)) {
width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
} else {

View File

@ -0,0 +1,123 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 26 Apr 2016 15:24:18 +0200
Subject: [PATCH] vga: factor out vga register setup
When enabling vbe mode qemu will setup a bunch of vga registers to make
sure the vga emulation operates in correct mode for a linear
framebuffer. Move that code to a separate function so we can call it
from other places too.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 7fa5c2c5dc9f9bf878c1e8669eb9644d70a71e71)
---
hw/display/vga.c | 78 ++++++++++++++++++++++++++++++++------------------------
1 file changed, 44 insertions(+), 34 deletions(-)
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 955ad6f..e46a2f8 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -642,6 +642,49 @@ static void vbe_fixup_regs(VGACommonState *s)
s->vbe_start_addr = offset / 4;
}
+/* we initialize the VGA graphic mode */
+static void vbe_update_vgaregs(VGACommonState *s)
+{
+ int h, shift_control;
+
+ if (!vbe_enabled(s)) {
+ /* vbe is turned off -- nothing to do */
+ return;
+ }
+
+ /* graphic mode + memory map 1 */
+ s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
+ VGA_GR06_GRAPHICS_MODE;
+ s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
+ s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
+ /* width */
+ s->cr[VGA_CRTC_H_DISP] =
+ (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
+ /* height (only meaningful if < 1024) */
+ h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
+ s->cr[VGA_CRTC_V_DISP_END] = h;
+ s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
+ ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
+ /* line compare to 1023 */
+ s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
+ s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
+ s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
+
+ if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
+ shift_control = 0;
+ s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
+ } else {
+ shift_control = 2;
+ /* set chain 4 mode */
+ s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
+ /* activate all planes */
+ s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
+ }
+ s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
+ (shift_control << 5);
+ s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
+}
+
static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
{
VGACommonState *s = opaque;
@@ -728,52 +771,19 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
case VBE_DISPI_INDEX_ENABLE:
if ((val & VBE_DISPI_ENABLED) &&
!(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
- int h, shift_control;
s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0;
s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
vbe_fixup_regs(s);
+ vbe_update_vgaregs(s);
/* clear the screen */
if (!(val & VBE_DISPI_NOCLEARMEM)) {
memset(s->vram_ptr, 0,
s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
}
-
- /* we initialize the VGA graphic mode */
- /* graphic mode + memory map 1 */
- s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
- VGA_GR06_GRAPHICS_MODE;
- s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
- s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
- /* width */
- s->cr[VGA_CRTC_H_DISP] =
- (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
- /* height (only meaningful if < 1024) */
- h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
- s->cr[VGA_CRTC_V_DISP_END] = h;
- s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
- ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
- /* line compare to 1023 */
- s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
- s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
- s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
-
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
- shift_control = 0;
- s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
- } else {
- shift_control = 2;
- /* set chain 4 mode */
- s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
- /* activate all planes */
- s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
- }
- s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
- (shift_control << 5);
- s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
} else {
s->bank_offset = 0;
}

View File

@ -0,0 +1,25 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 26 Apr 2016 15:39:22 +0200
Subject: [PATCH] vga: update vga register setup on vbe changes
Call the new vbe_update_vgaregs() function on vbe configuration
changes, to make sure vga registers are up-to-date.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 2068192dcccd8a80dddfcc8df6164cf9c26e0fc4)
---
hw/display/vga.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/display/vga.c b/hw/display/vga.c
index e46a2f8..ecfcf05 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -761,6 +761,7 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
case VBE_DISPI_INDEX_Y_OFFSET:
s->vbe_regs[s->vbe_index] = val;
vbe_fixup_regs(s);
+ vbe_update_vgaregs(s);
break;
case VBE_DISPI_INDEX_BANK:
val &= s->vbe_bank_mask;

View File

@ -0,0 +1,71 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 26 Apr 2016 14:48:06 +0200
Subject: [PATCH] vga: make sure vga register setup for vbe stays intact
(CVE-2016-3712).
Call vbe_update_vgaregs() when the guest touches GFX, SEQ or CRT
registers, to make sure the vga registers will always have the
values needed by vbe mode. This makes sure the sanity checks
applied by vbe_fixup_regs() are effective.
Without this guests can muck with shift_control, can turn on planar
vga modes or text mode emulation while VBE is active, making qemu
take code paths meant for CGA compatibility, but with the very
large display widths and heigts settable using VBE registers.
Which is good for one or another buffer overflow. Not that
critical as they typically read overflows happening somewhere
in the display code. So guests can DoS by crashing qemu with a
segfault, but it is probably not possible to break out of the VM.
Fixes: CVE-2016-3712
Reported-by: Zuozhi Fzz <zuozhi.fzz@alibaba-inc.com>
Reported-by: P J P <ppandit@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit fd3c136b3e1482cd0ec7285d6bc2a3e6a62c38d7)
---
hw/display/vga.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/hw/display/vga.c b/hw/display/vga.c
index ecfcf05..1fc8f12 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -140,6 +140,8 @@ static uint32_t expand4[256];
static uint16_t expand2[256];
static uint8_t expand4to8[16];
+static void vbe_update_vgaregs(VGACommonState *s);
+
static inline bool vbe_enabled(VGACommonState *s)
{
return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED;
@@ -482,6 +484,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
#endif
s->sr[s->sr_index] = val & sr_mask[s->sr_index];
+ vbe_update_vgaregs(s);
if (s->sr_index == VGA_SEQ_CLOCK_MODE) {
s->update_retrace_info(s);
}
@@ -513,6 +516,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
#endif
s->gr[s->gr_index] = val & gr_mask[s->gr_index];
+ vbe_update_vgaregs(s);
vga_update_memory_access(s);
break;
case VGA_CRT_IM:
@@ -531,10 +535,12 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
if (s->cr_index == VGA_CRTC_OVERFLOW) {
s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
(val & 0x10);
+ vbe_update_vgaregs(s);
}
return;
}
s->cr[s->cr_index] = val;
+ vbe_update_vgaregs(s);
switch(s->cr_index) {
case VGA_CRTC_H_TOTAL:

View File

@ -0,0 +1,37 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Wed, 21 Oct 2015 09:44:22 +0200
Subject: [PATCH] ehci: clear suspend bit on detach
When a device is detached, clear the suspend bit (PORTSC_SUSPEND)
in the port status register.
The specs are not *that* clear what is supposed to happen in case
a suspended device is unplugged. But the enable bit (PORTSC_PED)
is cleared, and the specs mention setting suspend with enable being
unset is undefined behavior. So clearing them both looks reasonable,
and it actually fixes the reported bug.
https://bugzilla.redhat.com/show_bug.cgi?id=1268879
Cc: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Message-id: 1445413462-18004-1-git-send-email-kraxel@redhat.com
(cherry picked from commit cbf82fa01e6fd4ecb234b235b10ffce548154a95)
---
hw/usb/hcd-ehci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 2f492d9..d6d7de3 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -726,7 +726,7 @@ static void ehci_detach(USBPort *port)
ehci_queues_rip_device(s, port->dev, 0);
ehci_queues_rip_device(s, port->dev, 1);
- *portsc &= ~(PORTSC_CONNECT|PORTSC_PED);
+ *portsc &= ~(PORTSC_CONNECT|PORTSC_PED|PORTSC_SUSPEND);
*portsc |= PORTSC_CSC;
ehci_raise_irq(s, USBSTS_PCD);

View File

@ -0,0 +1,59 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Mon, 18 Apr 2016 09:11:38 +0200
Subject: [PATCH] ehci: apply limit to iTD/sidt descriptors
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Commit "156a2e4 ehci: make idt processing more robust" tries to avoid a
DoS by the guest (create a circular iTD queue and let qemu ehci
emulation run in circles forever). Unfortunately this has two problems:
First it misses the case of siTDs, and second it reportedly breaks
FreeBSD.
So lets go for a different approach: just count the number of iTDs and
siTDs we have seen per frame and apply a limit. That should really
catch all cases now.
Reported-by: 杜少博 <dushaobo@360.cn>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 1ae3f2f178087711f9591350abad133525ba93f2)
---
hw/usb/hcd-ehci.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index d6d7de3..8dbfbe3 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2003,6 +2003,7 @@ static int ehci_state_writeback(EHCIQueue *q)
static void ehci_advance_state(EHCIState *ehci, int async)
{
EHCIQueue *q = NULL;
+ int itd_count = 0;
int again;
do {
@@ -2027,10 +2028,12 @@ static void ehci_advance_state(EHCIState *ehci, int async)
case EST_FETCHITD:
again = ehci_state_fetchitd(ehci, async);
+ itd_count++;
break;
case EST_FETCHSITD:
again = ehci_state_fetchsitd(ehci, async);
+ itd_count++;
break;
case EST_ADVANCEQUEUE:
@@ -2079,7 +2082,8 @@ static void ehci_advance_state(EHCIState *ehci, int async)
break;
}
- if (again < 0) {
+ if (again < 0 || itd_count > 16) {
+ /* TODO: notify guest (raise HSE irq?) */
fprintf(stderr, "processing error - resetting ehci HC\n");
ehci_reset(ehci);
again = 0;

View File

@ -0,0 +1,39 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Mon, 18 Apr 2016 09:20:54 +0200
Subject: [PATCH] Revert "ehci: make idt processing more robust"
This reverts commit 156a2e4dbffa85997636a7a39ef12da6f1b40254.
Breaks FreeBSD.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit a49923d2837d20510d645d3758f1ad87c32d0730)
---
hw/usb/hcd-ehci.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 8dbfbe3..ba5baf9 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1389,7 +1389,7 @@ static int ehci_process_itd(EHCIState *ehci,
{
USBDevice *dev;
USBEndpoint *ep;
- uint32_t i, len, pid, dir, devaddr, endp, xfers = 0;
+ uint32_t i, len, pid, dir, devaddr, endp;
uint32_t pg, off, ptr1, ptr2, max, mult;
ehci->periodic_sched_active = PERIODIC_ACTIVE;
@@ -1481,10 +1481,9 @@ static int ehci_process_itd(EHCIState *ehci,
ehci_raise_irq(ehci, USBSTS_INT);
}
itd->transact[i] &= ~ITD_XACT_ACTIVE;
- xfers++;
}
}
- return xfers ? 0 : -1;
+ return 0;
}

View File

@ -0,0 +1,44 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Fri, 8 Apr 2016 11:33:48 +0530
Subject: [PATCH] net: stellaris_enet: check packet length against receive
buffer
When receiving packets over Stellaris ethernet controller, it
uses receive buffer of size 2048 bytes. In case the controller
accepts large(MTU) packets, it could lead to memory corruption.
Add check to avoid it.
Reported-by: Oleksandr Bazhaniuk <oleksandr.bazhaniuk@intel.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 1460095428-22698-1-git-send-email-ppandit@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 3a15cc0e1ee7168db0782133d2607a6bfa422d66)
---
hw/net/stellaris_enet.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
index 278a654..90ada81 100644
--- a/hw/net/stellaris_enet.c
+++ b/hw/net/stellaris_enet.c
@@ -236,8 +236,18 @@ static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t *buf, si
n = s->next_packet + s->np;
if (n >= 31)
n -= 31;
- s->np++;
+ if (size >= sizeof(s->rx[n].data) - 6) {
+ /* If the packet won't fit into the
+ * emulated 2K RAM, this is reported
+ * as a FIFO overrun error.
+ */
+ s->ris |= SE_INT_FOV;
+ stellaris_enet_update(s);
+ return -1;
+ }
+
+ s->np++;
s->rx[n].len = size + 6;
p = s->rx[n].data;
*(p++) = (size + 6);

View File

@ -0,0 +1,95 @@
From: Ladi Prosek <lprosek@redhat.com>
Date: Thu, 3 Mar 2016 09:37:15 +0100
Subject: [PATCH] rng: remove the unused request cancellation code
rng_backend_cancel_requests had no callers and none of the code
deleted in this commit ever ran.
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Message-Id: <1456994238-9585-2-git-send-email-lprosek@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
(cherry picked from commit 3c52ddcdc548e7fbe65112d8a7bdc9cd105b4750)
---
backends/rng-egd.c | 12 ------------
backends/rng.c | 9 ---------
include/sysemu/rng.h | 11 -----------
3 files changed, 32 deletions(-)
diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index 2962795..0a42f05 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -124,17 +124,6 @@ static void rng_egd_free_requests(RngEgd *s)
s->requests = NULL;
}
-static void rng_egd_cancel_requests(RngBackend *b)
-{
- RngEgd *s = RNG_EGD(b);
-
- /* We simply delete the list of pending requests. If there is data in the
- * queue waiting to be read, this is okay, because there will always be
- * more data than we requested originally
- */
- rng_egd_free_requests(s);
-}
-
static void rng_egd_opened(RngBackend *b, Error **errp)
{
RngEgd *s = RNG_EGD(b);
@@ -211,7 +200,6 @@ static void rng_egd_class_init(ObjectClass *klass, void *data)
RngBackendClass *rbc = RNG_BACKEND_CLASS(klass);
rbc->request_entropy = rng_egd_request_entropy;
- rbc->cancel_requests = rng_egd_cancel_requests;
rbc->opened = rng_egd_opened;
}
diff --git a/backends/rng.c b/backends/rng.c
index 0f2fc11..b806140 100644
--- a/backends/rng.c
+++ b/backends/rng.c
@@ -25,15 +25,6 @@ void rng_backend_request_entropy(RngBackend *s, size_t size,
}
}
-void rng_backend_cancel_requests(RngBackend *s)
-{
- RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
-
- if (k->cancel_requests) {
- k->cancel_requests(s);
- }
-}
-
static bool rng_backend_prop_get_opened(Object *obj, Error **errp)
{
RngBackend *s = RNG_BACKEND(obj);
diff --git a/include/sysemu/rng.h b/include/sysemu/rng.h
index 0a27c9b..c7da17d 100644
--- a/include/sysemu/rng.h
+++ b/include/sysemu/rng.h
@@ -38,7 +38,6 @@ struct RngBackendClass
void (*request_entropy)(RngBackend *s, size_t size,
EntropyReceiveFunc *receive_entropy, void *opaque);
- void (*cancel_requests)(RngBackend *s);
void (*opened)(RngBackend *s, Error **errp);
};
@@ -69,14 +68,4 @@ struct RngBackend
void rng_backend_request_entropy(RngBackend *s, size_t size,
EntropyReceiveFunc *receive_entropy,
void *opaque);
-
-/**
- * rng_backend_cancel_requests:
- * @s: the backend to cancel all pending requests in
- *
- * Cancels all pending requests submitted by @rng_backend_request_entropy. This
- * should be used by a device during reset or in preparation for live migration
- * to stop tracking any request.
- */
-void rng_backend_cancel_requests(RngBackend *s);
#endif

View File

@ -0,0 +1,132 @@
From: Ladi Prosek <lprosek@redhat.com>
Date: Thu, 3 Mar 2016 09:37:16 +0100
Subject: [PATCH] rng: move request queue from RngEgd to RngBackend
The 'requests' field now lives in the RngBackend parent class.
There are no functional changes in this commit.
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Message-Id: <1456994238-9585-3-git-send-email-lprosek@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
(cherry picked from commit 74074e8a7c60592cf1cc6469dbc2550d24aeded3)
---
backends/rng-egd.c | 28 +++++++++-------------------
include/sysemu/rng.h | 11 +++++++++++
2 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index 0a42f05..e0d2860 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -24,19 +24,8 @@ typedef struct RngEgd
CharDriverState *chr;
char *chr_name;
-
- GSList *requests;
} RngEgd;
-typedef struct RngRequest
-{
- EntropyReceiveFunc *receive_entropy;
- uint8_t *data;
- void *opaque;
- size_t offset;
- size_t size;
-} RngRequest;
-
static void rng_egd_request_entropy(RngBackend *b, size_t size,
EntropyReceiveFunc *receive_entropy,
void *opaque)
@@ -65,7 +54,7 @@ static void rng_egd_request_entropy(RngBackend *b, size_t size,
size -= len;
}
- s->requests = g_slist_append(s->requests, req);
+ s->parent.requests = g_slist_append(s->parent.requests, req);
}
static void rng_egd_free_request(RngRequest *req)
@@ -80,7 +69,7 @@ static int rng_egd_chr_can_read(void *opaque)
GSList *i;
int size = 0;
- for (i = s->requests; i; i = i->next) {
+ for (i = s->parent.requests; i; i = i->next) {
RngRequest *req = i->data;
size += req->size - req->offset;
}
@@ -93,8 +82,8 @@ static void rng_egd_chr_read(void *opaque, const uint8_t *buf, int size)
RngEgd *s = RNG_EGD(opaque);
size_t buf_offset = 0;
- while (size > 0 && s->requests) {
- RngRequest *req = s->requests->data;
+ while (size > 0 && s->parent.requests) {
+ RngRequest *req = s->parent.requests->data;
int len = MIN(size, req->size - req->offset);
memcpy(req->data + req->offset, buf + buf_offset, len);
@@ -103,7 +92,8 @@ static void rng_egd_chr_read(void *opaque, const uint8_t *buf, int size)
size -= len;
if (req->offset == req->size) {
- s->requests = g_slist_remove_link(s->requests, s->requests);
+ s->parent.requests = g_slist_remove_link(s->parent.requests,
+ s->parent.requests);
req->receive_entropy(req->opaque, req->data, req->size);
@@ -116,12 +106,12 @@ static void rng_egd_free_requests(RngEgd *s)
{
GSList *i;
- for (i = s->requests; i; i = i->next) {
+ for (i = s->parent.requests; i; i = i->next) {
rng_egd_free_request(i->data);
}
- g_slist_free(s->requests);
- s->requests = NULL;
+ g_slist_free(s->parent.requests);
+ s->parent.requests = NULL;
}
static void rng_egd_opened(RngBackend *b, Error **errp)
diff --git a/include/sysemu/rng.h b/include/sysemu/rng.h
index c7da17d..084164c 100644
--- a/include/sysemu/rng.h
+++ b/include/sysemu/rng.h
@@ -25,6 +25,7 @@
#define RNG_BACKEND_CLASS(klass) \
OBJECT_CLASS_CHECK(RngBackendClass, (klass), TYPE_RNG_BACKEND)
+typedef struct RngRequest RngRequest;
typedef struct RngBackendClass RngBackendClass;
typedef struct RngBackend RngBackend;
@@ -32,6 +33,15 @@ typedef void (EntropyReceiveFunc)(void *opaque,
const void *data,
size_t size);
+struct RngRequest
+{
+ EntropyReceiveFunc *receive_entropy;
+ uint8_t *data;
+ void *opaque;
+ size_t offset;
+ size_t size;
+};
+
struct RngBackendClass
{
ObjectClass parent_class;
@@ -48,6 +58,7 @@ struct RngBackend
/*< protected >*/
bool opened;
+ GSList *requests;
};
/**

View File

@ -0,0 +1,160 @@
From: Ladi Prosek <lprosek@redhat.com>
Date: Thu, 3 Mar 2016 09:37:17 +0100
Subject: [PATCH] rng: move request queue cleanup from RngEgd to RngBackend
RngBackend is now in charge of cleaning up the linked list on
instance finalization. It also exposes a function to finalize
individual RngRequest instances, called by its child classes.
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Message-Id: <1456994238-9585-4-git-send-email-lprosek@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
(cherry picked from commit 9f14b0add1dcdbfa2ee61051d068211fb0a1fcc9)
---
backends/rng-egd.c | 25 +------------------------
backends/rng.c | 32 ++++++++++++++++++++++++++++++++
include/sysemu/rng.h | 12 ++++++++++++
3 files changed, 45 insertions(+), 24 deletions(-)
diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index e0d2860..df58f1d 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -57,12 +57,6 @@ static void rng_egd_request_entropy(RngBackend *b, size_t size,
s->parent.requests = g_slist_append(s->parent.requests, req);
}
-static void rng_egd_free_request(RngRequest *req)
-{
- g_free(req->data);
- g_free(req);
-}
-
static int rng_egd_chr_can_read(void *opaque)
{
RngEgd *s = RNG_EGD(opaque);
@@ -92,28 +86,13 @@ static void rng_egd_chr_read(void *opaque, const uint8_t *buf, int size)
size -= len;
if (req->offset == req->size) {
- s->parent.requests = g_slist_remove_link(s->parent.requests,
- s->parent.requests);
-
req->receive_entropy(req->opaque, req->data, req->size);
- rng_egd_free_request(req);
+ rng_backend_finalize_request(&s->parent, req);
}
}
}
-static void rng_egd_free_requests(RngEgd *s)
-{
- GSList *i;
-
- for (i = s->parent.requests; i; i = i->next) {
- rng_egd_free_request(i->data);
- }
-
- g_slist_free(s->parent.requests);
- s->parent.requests = NULL;
-}
-
static void rng_egd_opened(RngBackend *b, Error **errp)
{
RngEgd *s = RNG_EGD(b);
@@ -181,8 +160,6 @@ static void rng_egd_finalize(Object *obj)
}
g_free(s->chr_name);
-
- rng_egd_free_requests(s);
}
static void rng_egd_class_init(ObjectClass *klass, void *data)
diff --git a/backends/rng.c b/backends/rng.c
index b806140..437119c 100644
--- a/backends/rng.c
+++ b/backends/rng.c
@@ -63,6 +63,30 @@ static void rng_backend_prop_set_opened(Object *obj, bool value, Error **errp)
s->opened = true;
}
+static void rng_backend_free_request(RngRequest *req)
+{
+ g_free(req->data);
+ g_free(req);
+}
+
+static void rng_backend_free_requests(RngBackend *s)
+{
+ GSList *i;
+
+ for (i = s->requests; i; i = i->next) {
+ rng_backend_free_request(i->data);
+ }
+
+ g_slist_free(s->requests);
+ s->requests = NULL;
+}
+
+void rng_backend_finalize_request(RngBackend *s, RngRequest *req)
+{
+ s->requests = g_slist_remove(s->requests, req);
+ rng_backend_free_request(req);
+}
+
static void rng_backend_init(Object *obj)
{
object_property_add_bool(obj, "opened",
@@ -71,6 +95,13 @@ static void rng_backend_init(Object *obj)
NULL);
}
+static void rng_backend_finalize(Object *obj)
+{
+ RngBackend *s = RNG_BACKEND(obj);
+
+ rng_backend_free_requests(s);
+}
+
static void rng_backend_class_init(ObjectClass *oc, void *data)
{
UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
@@ -83,6 +114,7 @@ static const TypeInfo rng_backend_info = {
.parent = TYPE_OBJECT,
.instance_size = sizeof(RngBackend),
.instance_init = rng_backend_init,
+ .instance_finalize = rng_backend_finalize,
.class_size = sizeof(RngBackendClass),
.class_init = rng_backend_class_init,
.abstract = true,
diff --git a/include/sysemu/rng.h b/include/sysemu/rng.h
index 084164c..c2c9035 100644
--- a/include/sysemu/rng.h
+++ b/include/sysemu/rng.h
@@ -61,6 +61,7 @@ struct RngBackend
GSList *requests;
};
+
/**
* rng_backend_request_entropy:
* @s: the backend to request entropy from
@@ -79,4 +80,15 @@ struct RngBackend
void rng_backend_request_entropy(RngBackend *s, size_t size,
EntropyReceiveFunc *receive_entropy,
void *opaque);
+
+/**
+ * rng_backend_free_request:
+ * @s: the backend that created the request
+ * @req: the request to finalize
+ *
+ * Used by child rng backend classes to finalize requests once they've been
+ * processed. The request is removed from the list of active requests and
+ * deleted.
+ */
+void rng_backend_finalize_request(RngBackend *s, RngRequest *req);
#endif

View File

@ -0,0 +1,176 @@
From: Ladi Prosek <lprosek@redhat.com>
Date: Thu, 3 Mar 2016 09:37:18 +0100
Subject: [PATCH] rng: add request queue support to rng-random
Requests are now created in the RngBackend parent class and the
code path is shared by both rng-egd and rng-random.
This commit fixes the rng-random implementation which processed
only one request at a time and simply discarded all but the most
recent one. In the guest this manifested as delayed completion
of reads from virtio-rng, i.e. a read was completed only after
another read was issued.
By switching rng-random to use the same request queue as rng-egd,
the unsafe stack-based allocation of the entropy buffer is
eliminated and replaced with g_malloc.
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Message-Id: <1456994238-9585-5-git-send-email-lprosek@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
(cherry picked from commit 60253ed1e6ec6d8e5ef2efe7bf755f475dce9956)
---
backends/rng-egd.c | 16 ++--------------
backends/rng-random.c | 43 +++++++++++++++++++------------------------
backends/rng.c | 13 ++++++++++++-
include/sysemu/rng.h | 3 +--
4 files changed, 34 insertions(+), 41 deletions(-)
diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index df58f1d..9c6bde4 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -26,20 +26,10 @@ typedef struct RngEgd
char *chr_name;
} RngEgd;
-static void rng_egd_request_entropy(RngBackend *b, size_t size,
- EntropyReceiveFunc *receive_entropy,
- void *opaque)
+static void rng_egd_request_entropy(RngBackend *b, RngRequest *req)
{
RngEgd *s = RNG_EGD(b);
- RngRequest *req;
-
- req = g_malloc(sizeof(*req));
-
- req->offset = 0;
- req->size = size;
- req->receive_entropy = receive_entropy;
- req->opaque = opaque;
- req->data = g_malloc(req->size);
+ size_t size = req->size;
while (size > 0) {
uint8_t header[2];
@@ -53,8 +43,6 @@ static void rng_egd_request_entropy(RngBackend *b, size_t size,
size -= len;
}
-
- s->parent.requests = g_slist_append(s->parent.requests, req);
}
static int rng_egd_chr_can_read(void *opaque)
diff --git a/backends/rng-random.c b/backends/rng-random.c
index 4f85a8e..fc0bc75 100644
--- a/backends/rng-random.c
+++ b/backends/rng-random.c
@@ -21,10 +21,6 @@ struct RndRandom
int fd;
char *filename;
-
- EntropyReceiveFunc *receive_func;
- void *opaque;
- size_t size;
};
/**
@@ -37,36 +33,35 @@ struct RndRandom
static void entropy_available(void *opaque)
{
RndRandom *s = RNG_RANDOM(opaque);
- uint8_t buffer[s->size];
- ssize_t len;
- len = read(s->fd, buffer, s->size);
- if (len < 0 && errno == EAGAIN) {
- return;
- }
- g_assert(len != -1);
+ while (s->parent.requests != NULL) {
+ RngRequest *req = s->parent.requests->data;
+ ssize_t len;
+
+ len = read(s->fd, req->data, req->size);
+ if (len < 0 && errno == EAGAIN) {
+ return;
+ }
+ g_assert(len != -1);
- s->receive_func(s->opaque, buffer, len);
- s->receive_func = NULL;
+ req->receive_entropy(req->opaque, req->data, len);
+ rng_backend_finalize_request(&s->parent, req);
+ }
+
+ /* We've drained all requests, the fd handler can be reset. */
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
}
-static void rng_random_request_entropy(RngBackend *b, size_t size,
- EntropyReceiveFunc *receive_entropy,
- void *opaque)
+static void rng_random_request_entropy(RngBackend *b, RngRequest *req)
{
RndRandom *s = RNG_RANDOM(b);
- if (s->receive_func) {
- s->receive_func(s->opaque, NULL, 0);
+ if (s->parent.requests == NULL) {
+ /* If there are no pending requests yet, we need to
+ * install our fd handler. */
+ qemu_set_fd_handler(s->fd, entropy_available, NULL, s);
}
-
- s->receive_func = receive_entropy;
- s->opaque = opaque;
- s->size = size;
-
- qemu_set_fd_handler(s->fd, entropy_available, NULL, s);
}
static void rng_random_opened(RngBackend *b, Error **errp)
diff --git a/backends/rng.c b/backends/rng.c
index 437119c..3383e01 100644
--- a/backends/rng.c
+++ b/backends/rng.c
@@ -19,9 +19,20 @@ void rng_backend_request_entropy(RngBackend *s, size_t size,
void *opaque)
{
RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
+ RngRequest *req;
if (k->request_entropy) {
- k->request_entropy(s, size, receive_entropy, opaque);
+ req = g_malloc(sizeof(*req));
+
+ req->offset = 0;
+ req->size = size;
+ req->receive_entropy = receive_entropy;
+ req->opaque = opaque;
+ req->data = g_malloc(req->size);
+
+ k->request_entropy(s, req);
+
+ s->requests = g_slist_append(s->requests, req);
}
}
diff --git a/include/sysemu/rng.h b/include/sysemu/rng.h
index c2c9035..a7ed580 100644
--- a/include/sysemu/rng.h
+++ b/include/sysemu/rng.h
@@ -46,8 +46,7 @@ struct RngBackendClass
{
ObjectClass parent_class;
- void (*request_entropy)(RngBackend *s, size_t size,
- EntropyReceiveFunc *receive_entropy, void *opaque);
+ void (*request_entropy)(RngBackend *s, RngRequest *req);
void (*opened)(RngBackend *s, Error **errp);
};

View File

@ -0,0 +1,96 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Mon, 22 Feb 2016 09:50:11 +0100
Subject: [PATCH] ohci: allocate timer only once.
Allocate timer once, at init time, instead of allocating/freeing
it all the time when starting/stopping the bus. Simplifies the
code, also fixes bugs (memory leak) due to missing checks whenever
the time is already allocated or not.
Cc: Prasad J Pandit <pjp@fedoraproject.org>
Reported-by: Zuozhi Fzz <zuozhi.fzz@alibaba-inc.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit fa1298c2d623522eda7b4f1f721fcb935abb7360)
---
hw/usb/hcd-ohci.c | 34 ++++++++--------------------------
1 file changed, 8 insertions(+), 26 deletions(-)
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 1a22c9c..4b13d3c 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1331,16 +1331,6 @@ static void ohci_frame_boundary(void *opaque)
*/
static int ohci_bus_start(OHCIState *ohci)
{
- ohci->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
- ohci_frame_boundary,
- ohci);
-
- if (ohci->eof_timer == NULL) {
- trace_usb_ohci_bus_eof_timer_failed(ohci->name);
- ohci_die(ohci);
- return 0;
- }
-
trace_usb_ohci_start(ohci->name);
ohci_sof(ohci);
@@ -1352,11 +1342,7 @@ static int ohci_bus_start(OHCIState *ohci)
static void ohci_bus_stop(OHCIState *ohci)
{
trace_usb_ohci_stop(ohci->name);
- if (ohci->eof_timer) {
- timer_del(ohci->eof_timer);
- timer_free(ohci->eof_timer);
- }
- ohci->eof_timer = NULL;
+ timer_del(ohci->eof_timer);
}
/* Sets a flag in a port status register but only set it if the port is
@@ -1883,6 +1869,9 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
usb_packet_init(&ohci->usb_packet);
ohci->async_td = 0;
+
+ ohci->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+ ohci_frame_boundary, ohci);
}
#define TYPE_PCI_OHCI "pci-ohci"
@@ -1952,6 +1941,9 @@ static void usb_ohci_exit(PCIDevice *dev)
if (!ohci->masterbus) {
usb_bus_release(&s->bus);
}
+
+ timer_del(s->eof_timer);
+ timer_free(s->eof_timer);
}
static void usb_ohci_reset_pci(DeviceState *d)
@@ -2017,23 +2009,13 @@ static bool ohci_eof_timer_needed(void *opaque)
{
OHCIState *ohci = opaque;
- return ohci->eof_timer != NULL;
-}
-
-static int ohci_eof_timer_pre_load(void *opaque)
-{
- OHCIState *ohci = opaque;
-
- ohci_bus_start(ohci);
-
- return 0;
+ return timer_pending(ohci->eof_timer);
}
static const VMStateDescription vmstate_ohci_eof_timer = {
.name = "ohci-core/eof-timer",
.version_id = 1,
.minimum_version_id = 1,
- .pre_load = ohci_eof_timer_pre_load,
.fields = (VMStateField[]) {
VMSTATE_TIMER_PTR(eof_timer, OHCIState),
VMSTATE_END_OF_LIST()

View File

@ -0,0 +1,43 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Fri, 29 Jan 2016 18:30:34 +0530
Subject: [PATCH] usb: ehci: add capability mmio write function
USB Ehci emulation supports host controller capability registers.
But its mmio '.write' function was missing, which lead to a null
pointer dereference issue. Add a do nothing 'ehci_caps_write'
definition to avoid it; Do nothing because capability registers
are Read Only(RO).
Reported-by: Zuozhi Fzz <zuozhi.fzz@alibaba-inc.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 1454072434-16045-1-git-send-email-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit dff0367cf66f489aa772320fa2937a8cac1ca30d)
---
hw/usb/hcd-ehci.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index ba5baf9..5946955 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -893,6 +893,11 @@ static uint64_t ehci_caps_read(void *ptr, hwaddr addr,
return s->caps[addr];
}
+static void ehci_caps_write(void *ptr, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+}
+
static uint64_t ehci_opreg_read(void *ptr, hwaddr addr,
unsigned size)
{
@@ -2316,6 +2321,7 @@ static void ehci_frame_timer(void *opaque)
static const MemoryRegionOps ehci_mmio_caps_ops = {
.read = ehci_caps_read,
+ .write = ehci_caps_write,
.valid.min_access_size = 1,
.valid.max_access_size = 4,
.impl.min_access_size = 1,

View File

@ -0,0 +1,38 @@
From: John Snow <jsnow@redhat.com>
Date: Wed, 28 Oct 2015 13:56:40 -0400
Subject: [PATCH] configure: disallow ccache during compile tests
If the user is using ccache during the configuration step,
it may interfere with some of the configuration tests,
particularly the "Is ccache interfering with macro analysis" step,
which is a bit of a poetic problem.
1) Disallow ccache from reading from the cache during configure,
but don't disable it entirely to allow us to see if it causes other
problems.
2) Force off CCACHE_CPP2 during the ccache test to get a deterministic
answer over whether or not we need to enable that feature later.
Signed-off-by: John Snow <jsnow@redhat.com>
Message-Id: <1446055000-29150-1-git-send-email-jsnow@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 5e4dfd3d4e87e0464d599ecef06aa8fe78420a9b)
---
configure | 3 +++
1 file changed, 3 insertions(+)
diff --git a/configure b/configure
index 69a5e2d..b29c923 100755
--- a/configure
+++ b/configure
@@ -8,6 +8,9 @@
CLICOLOR_FORCE= GREP_OPTIONS=
unset CLICOLOR_FORCE GREP_OPTIONS
+# Don't allow CCACHE, if present, to use cached results of compile tests!
+export CCACHE_RECACHE=yes
+
# Temporary directory used for files created while
# configure runs. Since it is in the build directory
# we can safely blow away any previous version of it

View File

@ -43,7 +43,7 @@
Summary: QEMU is a FAST! processor emulator
Name: qemu
Version: 2.3.1
Release: 13%{?dist}
Release: 14%{?dist}
Epoch: 2
License: GPLv2+ and LGPLv2+ and BSD
Group: Development/Tools
@ -176,6 +176,31 @@ Patch0106: 0106-net-check-packet-payload-length.patch
Patch0107: 0107-usb-check-USB-configuration-descriptor-object.patch
# spice: fix spice_chr_add_watch() crash (bz #1315049)
Patch0108: 0108-spice-fix-spice_chr_add_watch-pre-condition.patch
# CVE-2016-3710: incorrect bounds checking in vga (bz #1334345)
Patch0109: 0109-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch
Patch0110: 0110-vga-add-vbe_enabled-helper.patch
Patch0111: 0111-vga-factor-out-vga-register-setup.patch
Patch0112: 0112-vga-update-vga-register-setup-on-vbe-changes.patch
# CVE-2016-3712: out of bounds read in vga (bz #1334342)
Patch0113: 0113-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch
# Fix USB redirection (bz #1330221)
Patch0114: 0114-ehci-clear-suspend-bit-on-detach.patch
# CVE-2016-4037: infinite loop in usb ehci (bz #1328080)
Patch0115: 0115-ehci-apply-limit-to-iTD-sidt-descriptors.patch
Patch0116: 0116-Revert-ehci-make-idt-processing-more-robust.patch
# CVE-2016-4001: buffer overflow in stellaris net (bz #1325885)
Patch0117: 0117-net-stellaris_enet-check-packet-length-against-recei.patch
# CVE-2016-2858: rng stack corruption (bz #1314677)
Patch0118: 0118-rng-remove-the-unused-request-cancellation-code.patch
Patch0119: 0119-rng-move-request-queue-from-RngEgd-to-RngBackend.patch
Patch0120: 0120-rng-move-request-queue-cleanup-from-RngEgd-to-RngBac.patch
Patch0121: 0121-rng-add-request-queue-support-to-rng-random.patch
# CVE-2016-2391: ohci: crash via multiple timers (bz #1308881)
Patch0122: 0122-ohci-allocate-timer-only-once.patch
# CVE-2016-2198: ehci: null pointer dereference (bz #1303134)
Patch0123: 0123-usb-ehci-add-capability-mmio-write-function.patch
# Fix ./configure with ccache
Patch0124: 0124-configure-disallow-ccache-during-compile-tests.patch
BuildRequires: SDL2-devel
BuildRequires: zlib-devel
@ -1278,6 +1303,17 @@ getent passwd qemu >/dev/null || \
%changelog
* Mon May 09 2016 Cole Robinson <crobinso@redhat.com> - 2:2.3.1-14
- CVE-2016-3710: incorrect bounds checking in vga (bz #1334345)
- CVE-2016-3712: out of bounds read in vga (bz #1334342)
- Fix USB redirection (bz #1330221)
- CVE-2016-4037: infinite loop in usb ehci (bz #1328080)
- CVE-2016-4001: buffer overflow in stellaris net (bz #1325885)
- CVE-2016-2858: rng stack corruption (bz #1314677)
- CVE-2016-2391: ohci: crash via multiple timers (bz #1308881)
- CVE-2016-2198: ehci: null pointer dereference (bz #1303134)
- Fix ./configure with ccache
* Thu Mar 17 2016 Cole Robinson <crobinso@redhat.com> - 2:2.3.1-13
- CVE-2016-2538: Integer overflow in usb module (bz #1305815)
- CVE-2016-2841: ne2000: infinite loop (bz #1304047)