diff options
Diffstat (limited to 'app-emulation/qemu/files/qemu-4.2.0-ati-vga-crash.patch')
-rw-r--r-- | app-emulation/qemu/files/qemu-4.2.0-ati-vga-crash.patch | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/app-emulation/qemu/files/qemu-4.2.0-ati-vga-crash.patch b/app-emulation/qemu/files/qemu-4.2.0-ati-vga-crash.patch new file mode 100644 index 000000000000..5f442f0fd07a --- /dev/null +++ b/app-emulation/qemu/files/qemu-4.2.0-ati-vga-crash.patch @@ -0,0 +1,94 @@ +https://bugs.gentoo.org/719266 + +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> +--- + hw/display/ati_2d.c | 37 ++++++++++++++++++++++++++----------- + 1 file changed, 26 insertions(+), 11 deletions(-) + +--- 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.26.2 + |