ati_bpp_from_datatype() returns 0 for unrecognized dp_datatype nibble
values (0, 1, or >= 7). ati_host_data_flush() only guards against the
bpp == 24 case but not bpp == 0, leading to:
1. Division by zero at "pix_count /= ctx.bpp" (SIGFPE) when
src_datatype is SRC_COLOR.
2. g_assert_not_reached() in stn_he_p() when bypp (= bpp/8 = 0)
hits the default case of the size switch.
Both are guest-triggerable via MMIO writes to the dp_datatype register
while a HOST_DATA blit is active.
Add an explicit bpp == 0 check with LOG_GUEST_ERROR before proceeding
with the blit, consistent with the existing check in ati_2d_do_blt().
Reported-by: Feifan Qian <[email protected]>
Cc: [email protected]
Signed-off-by: Junjie Cao <[email protected]>
---
hw/display/ati_2d.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
index 8ef82bb87f..22dd811bd8 100644
--- a/hw/display/ati_2d.c
+++ b/hw/display/ati_2d.c
@@ -377,6 +377,11 @@ bool ati_host_data_flush(ATIVGAState *s)
setup_2d_blt_ctx(s, &ctx);
+ if (!ctx.bpp) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "host_data_blt: invalid bpp from datatype\n");
+ return false;
+ }
if (ctx.bpp == 24) {
qemu_log_mask(LOG_UNIMP,
"host_data_blt: unsupported in 24 bits mode\n");
--
2.43.0