!41 Fix CVE-2020-11869 and CVE-2019-20175
Merge pull request !41 from FangYing/openEuler-20.03-LTS
This commit is contained in:
commit
2a3c6ba49d
91
ati-vga-Fix-checks-in-ati_2d_blt-to-avoid-crash.patch
Normal file
91
ati-vga-Fix-checks-in-ati_2d_blt-to-avoid-crash.patch
Normal file
@ -0,0 +1,91 @@
|
||||
From ac2071c3791b67fc7af78b8ceb320c01ca1b5df7 Mon Sep 17 00:00:00 2001
|
||||
From: BALATON Zoltan <balaton@eik.bme.hu>
|
||||
Date: Mon, 6 Apr 2020 22:34:26 +0200
|
||||
Subject: [PATCH] ati-vga: Fix checks in ati_2d_blt() to avoid crash
|
||||
|
||||
In some corner cases (that never happen during normal operation but a
|
||||
malicious guest could program wrong values) pixman functions were
|
||||
called with parameters that result in a crash. Fix this and add more
|
||||
checks to disallow such cases.
|
||||
|
||||
Reported-by: Ziming Zhang <ezrakiez@gmail.com>
|
||||
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
|
||||
Message-id: 20200406204029.19559747D5D@zero.eik.bme.hu
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
|
||||
diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
|
||||
index 42e82311eb..23a8ae0cd8 100644
|
||||
--- a/hw/display/ati_2d.c
|
||||
+++ b/hw/display/ati_2d.c
|
||||
@@ -53,12 +53,20 @@ void ati_2d_blt(ATIVGAState *s)
|
||||
s->vga.vbe_start_addr, surface_data(ds), surface_stride(ds),
|
||||
surface_bits_per_pixel(ds),
|
||||
(s->regs.dp_mix & GMC_ROP3_MASK) >> 16);
|
||||
- int dst_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
|
||||
- s->regs.dst_x : s->regs.dst_x + 1 - s->regs.dst_width);
|
||||
- int dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
|
||||
- s->regs.dst_y : s->regs.dst_y + 1 - s->regs.dst_height);
|
||||
+ unsigned dst_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
|
||||
+ s->regs.dst_x : s->regs.dst_x + 1 - s->regs.dst_width);
|
||||
+ unsigned dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
|
||||
+ s->regs.dst_y : s->regs.dst_y + 1 - s->regs.dst_height);
|
||||
int bpp = ati_bpp_from_datatype(s);
|
||||
+ if (!bpp) {
|
||||
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid bpp\n");
|
||||
+ return;
|
||||
+ }
|
||||
int dst_stride = DEFAULT_CNTL ? s->regs.dst_pitch : s->regs.default_pitch;
|
||||
+ if (!dst_stride) {
|
||||
+ qemu_log_mask(LOG_GUEST_ERROR, "Zero dest pitch\n");
|
||||
+ return;
|
||||
+ }
|
||||
uint8_t *dst_bits = s->vga.vram_ptr + (DEFAULT_CNTL ?
|
||||
s->regs.dst_offset : s->regs.default_offset);
|
||||
|
||||
@@ -82,12 +90,16 @@ void ati_2d_blt(ATIVGAState *s)
|
||||
switch (s->regs.dp_mix & GMC_ROP3_MASK) {
|
||||
case ROP3_SRCCOPY:
|
||||
{
|
||||
- int src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
|
||||
- s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width);
|
||||
- int src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
|
||||
- s->regs.src_y : s->regs.src_y + 1 - s->regs.dst_height);
|
||||
+ unsigned src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
|
||||
+ s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width);
|
||||
+ unsigned src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
|
||||
+ s->regs.src_y : s->regs.src_y + 1 - s->regs.dst_height);
|
||||
int src_stride = DEFAULT_CNTL ?
|
||||
s->regs.src_pitch : s->regs.default_pitch;
|
||||
+ if (!src_stride) {
|
||||
+ qemu_log_mask(LOG_GUEST_ERROR, "Zero source pitch\n");
|
||||
+ return;
|
||||
+ }
|
||||
uint8_t *src_bits = s->vga.vram_ptr + (DEFAULT_CNTL ?
|
||||
s->regs.src_offset : s->regs.default_offset);
|
||||
|
||||
@@ -137,8 +149,10 @@ void ati_2d_blt(ATIVGAState *s)
|
||||
dst_y * surface_stride(ds),
|
||||
s->regs.dst_height * surface_stride(ds));
|
||||
}
|
||||
- s->regs.dst_x += s->regs.dst_width;
|
||||
- s->regs.dst_y += s->regs.dst_height;
|
||||
+ s->regs.dst_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
|
||||
+ dst_x + s->regs.dst_width : dst_x);
|
||||
+ s->regs.dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
|
||||
+ dst_y + s->regs.dst_height : dst_y);
|
||||
break;
|
||||
}
|
||||
case ROP3_PATCOPY:
|
||||
@@ -179,7 +193,8 @@ void ati_2d_blt(ATIVGAState *s)
|
||||
dst_y * surface_stride(ds),
|
||||
s->regs.dst_height * surface_stride(ds));
|
||||
}
|
||||
- s->regs.dst_y += s->regs.dst_height;
|
||||
+ s->regs.dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
|
||||
+ dst_y + s->regs.dst_height : dst_y);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
--
|
||||
2.23.0
|
||||
|
||||
89
ide-Fix-incorrect-handling-of-some-PRDTs-in-ide_dma_.patch
Normal file
89
ide-Fix-incorrect-handling-of-some-PRDTs-in-ide_dma_.patch
Normal file
@ -0,0 +1,89 @@
|
||||
From ed78352a59ea7acf7520d4d47a96b9911bae7fc3 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Popov <alex.popov@linux.com>
|
||||
Date: Mon, 23 Dec 2019 20:51:16 +0300
|
||||
Subject: [PATCH] ide: Fix incorrect handling of some PRDTs in ide_dma_cb()
|
||||
|
||||
The commit a718978ed58a from July 2015 introduced the assertion which
|
||||
implies that the size of successful DMA transfers handled in ide_dma_cb()
|
||||
should be multiple of 512 (the size of a sector). But guest systems can
|
||||
initiate DMA transfers that don't fit this requirement.
|
||||
|
||||
For fixing that let's check the number of bytes prepared for the transfer
|
||||
by the prepare_buf() handler. The code in ide_dma_cb() must behave
|
||||
according to the Programming Interface for Bus Master IDE Controller
|
||||
(Revision 1.0 5/16/94):
|
||||
1. If PRDs specified a smaller size than the IDE transfer
|
||||
size, then the Interrupt and Active bits in the Controller
|
||||
status register are not set (Error Condition).
|
||||
2. If the size of the physical memory regions was equal to
|
||||
the IDE device transfer size, the Interrupt bit in the
|
||||
Controller status register is set to 1, Active bit is set to 0.
|
||||
3. If PRDs specified a larger size than the IDE transfer size,
|
||||
the Interrupt and Active bits in the Controller status register
|
||||
are both set to 1.
|
||||
|
||||
Signed-off-by: Alexander Popov <alex.popov@linux.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-id: 20191223175117.508990-2-alex.popov@linux.com
|
||||
Signed-off-by: John Snow <jsnow@redhat.com>
|
||||
|
||||
diff --git a/hw/ide/core.c b/hw/ide/core.c
|
||||
index 754ff4dc34..80000eb766 100644
|
||||
--- a/hw/ide/core.c
|
||||
+++ b/hw/ide/core.c
|
||||
@@ -849,6 +849,7 @@ static void ide_dma_cb(void *opaque, int ret)
|
||||
int64_t sector_num;
|
||||
uint64_t offset;
|
||||
bool stay_active = false;
|
||||
+ int32_t prep_size = 0;
|
||||
|
||||
if (ret == -EINVAL) {
|
||||
ide_dma_error(s);
|
||||
@@ -863,13 +864,15 @@ static void ide_dma_cb(void *opaque, int ret)
|
||||
}
|
||||
}
|
||||
|
||||
- n = s->io_buffer_size >> 9;
|
||||
- if (n > s->nsector) {
|
||||
- /* The PRDs were longer than needed for this request. Shorten them so
|
||||
- * we don't get a negative remainder. The Active bit must remain set
|
||||
- * after the request completes. */
|
||||
+ if (s->io_buffer_size > s->nsector * 512) {
|
||||
+ /*
|
||||
+ * The PRDs were longer than needed for this request.
|
||||
+ * The Active bit must remain set after the request completes.
|
||||
+ */
|
||||
n = s->nsector;
|
||||
stay_active = true;
|
||||
+ } else {
|
||||
+ n = s->io_buffer_size >> 9;
|
||||
}
|
||||
|
||||
sector_num = ide_get_sector(s);
|
||||
@@ -892,9 +895,20 @@ static void ide_dma_cb(void *opaque, int ret)
|
||||
n = s->nsector;
|
||||
s->io_buffer_index = 0;
|
||||
s->io_buffer_size = n * 512;
|
||||
- if (s->bus->dma->ops->prepare_buf(s->bus->dma, s->io_buffer_size) < 512) {
|
||||
- /* The PRDs were too short. Reset the Active bit, but don't raise an
|
||||
- * interrupt. */
|
||||
+ prep_size = s->bus->dma->ops->prepare_buf(s->bus->dma, s->io_buffer_size);
|
||||
+ /* prepare_buf() must succeed and respect the limit */
|
||||
+ assert(prep_size >= 0 && prep_size <= n * 512);
|
||||
+
|
||||
+ /*
|
||||
+ * Now prep_size stores the number of bytes in the sglist, and
|
||||
+ * s->io_buffer_size stores the number of bytes described by the PRDs.
|
||||
+ */
|
||||
+
|
||||
+ if (prep_size < n * 512) {
|
||||
+ /*
|
||||
+ * The PRDs are too short for this request. Error condition!
|
||||
+ * Reset the Active bit and don't raise the interrupt.
|
||||
+ */
|
||||
s->status = READY_STAT | SEEK_STAT;
|
||||
dma_buf_commit(s, 0);
|
||||
goto eot;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
Name: qemu
|
||||
Version: 4.1.0
|
||||
Release: 7
|
||||
Release: 8
|
||||
Epoch: 2
|
||||
Summary: QEMU is a generic and open source machine emulator and virtualizer
|
||||
License: GPLv2 and BSD and MIT and CC-BY
|
||||
@ -162,6 +162,8 @@ Patch0149: migration-ram-Do-error_free-after-migrate_set_error-.patch
|
||||
Patch0150: migration-ram-fix-memleaks-in-multifd_new_send_chann.patch
|
||||
Patch0151: migration-rdma-fix-a-memleak-on-error-path-in-rdma_s.patch
|
||||
Patch0152: arm-virt-Support-CPU-cold-plug.patch
|
||||
Patch0153: ide-Fix-incorrect-handling-of-some-PRDTs-in-ide_dma_.patch
|
||||
Patch0154: ati-vga-Fix-checks-in-ati_2d_blt-to-avoid-crash.patch
|
||||
|
||||
BuildRequires: flex
|
||||
BuildRequires: bison
|
||||
@ -507,6 +509,10 @@ getent passwd qemu >/dev/null || \
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri May 15 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- ide: Fix incorrect handling of some PRDTs in ide_dma_cb()
|
||||
- ati-vga: Fix checks in ati_2d_blt() to avoid crash
|
||||
|
||||
* Tue May 12 2020 Huawei Technologies Co., Ltd. <zhukeqian1@huawei.com>
|
||||
- arm/virt: Support CPU cold plug
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user