From ec1a227b4893b3be0228e7f1ac924a329157f18c Mon Sep 17 00:00:00 2001 From: Ying Fang Date: Fri, 15 May 2020 15:33:14 +0800 Subject: [PATCH 1/3] CVE: fix CVE-2019-20175 backport patch from upstream: https://git.qemu.org/?p=qemu.git;a=commitdiff;h=ed78352a59ea7acf7520d4d47a96b9911bae7fc3 Signed-off-by: Ying Fang --- ...t-handling-of-some-PRDTs-in-ide_dma_.patch | 89 +++++++++++++++++++ qemu.spec | 4 + 2 files changed, 93 insertions(+) create mode 100644 ide-Fix-incorrect-handling-of-some-PRDTs-in-ide_dma_.patch diff --git a/ide-Fix-incorrect-handling-of-some-PRDTs-in-ide_dma_.patch b/ide-Fix-incorrect-handling-of-some-PRDTs-in-ide_dma_.patch new file mode 100644 index 00000000..9570b46b --- /dev/null +++ b/ide-Fix-incorrect-handling-of-some-PRDTs-in-ide_dma_.patch @@ -0,0 +1,89 @@ +From ed78352a59ea7acf7520d4d47a96b9911bae7fc3 Mon Sep 17 00:00:00 2001 +From: Alexander Popov +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 +Reviewed-by: Kevin Wolf +Message-id: 20191223175117.508990-2-alex.popov@linux.com +Signed-off-by: John Snow + +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 + diff --git a/qemu.spec b/qemu.spec index 5243270b..beb12ea6 100644 --- a/qemu.spec +++ b/qemu.spec @@ -162,6 +162,7 @@ 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 BuildRequires: flex BuildRequires: bison @@ -507,6 +508,9 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Fri May 15 2020 Huawei Technologies Co., Ltd. +- ide: Fix incorrect handling of some PRDTs in ide_dma_cb() + * Tue May 12 2020 Huawei Technologies Co., Ltd. - arm/virt: Support CPU cold plug -- Gitee From 6fc286684c76bf40cd3981b45ff5fc22e1a700a7 Mon Sep 17 00:00:00 2001 From: Ying Fang Date: Fri, 15 May 2020 15:47:11 +0800 Subject: [PATCH 2/3] CVE: fix CVE-2020-11869 backport from qemu upstream: https://git.qemu.org/?p=qemu.git;a=commit;h=ac2071c3791b67fc7af78b8ceb320c01ca1b5df7 Signed-off-by: Ying Fang --- ...-checks-in-ati_2d_blt-to-avoid-crash.patch | 91 +++++++++++++++++++ qemu.spec | 2 + 2 files changed, 93 insertions(+) create mode 100644 ati-vga-Fix-checks-in-ati_2d_blt-to-avoid-crash.patch diff --git a/ati-vga-Fix-checks-in-ati_2d_blt-to-avoid-crash.patch b/ati-vga-Fix-checks-in-ati_2d_blt-to-avoid-crash.patch new file mode 100644 index 00000000..ef1d8b64 --- /dev/null +++ b/ati-vga-Fix-checks-in-ati_2d_blt-to-avoid-crash.patch @@ -0,0 +1,91 @@ +From ac2071c3791b67fc7af78b8ceb320c01ca1b5df7 Mon Sep 17 00:00:00 2001 +From: BALATON Zoltan +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 +Signed-off-by: BALATON Zoltan +Message-id: 20200406204029.19559747D5D@zero.eik.bme.hu +Signed-off-by: Gerd Hoffmann + +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 + diff --git a/qemu.spec b/qemu.spec index beb12ea6..f140c99f 100644 --- a/qemu.spec +++ b/qemu.spec @@ -163,6 +163,7 @@ 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 @@ -510,6 +511,7 @@ getent passwd qemu >/dev/null || \ %changelog * Fri May 15 2020 Huawei Technologies Co., Ltd. - 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. - arm/virt: Support CPU cold plug -- Gitee From e74fdc8befb8ec84a9aac0c335b534cc808a3979 Mon Sep 17 00:00:00 2001 From: Ying Fang Date: Fri, 15 May 2020 15:49:58 +0800 Subject: [PATCH 3/3] spec: Update release version increase release version by one Signed-off-by: Ying Fang --- qemu.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu.spec b/qemu.spec index f140c99f..84e30653 100644 --- a/qemu.spec +++ b/qemu.spec @@ -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 -- Gitee