@samitouri / QOSamiQemu / commits / 3565faa0ac

hw/display/ati: reset host_data.next in write handler after flush

ati_host_data_flush() resets host_data.next only on its success path. When it returns early (unsupported bpp, direction, src_source, or src_datatype), next remains stale at >= 4. The next HOST_DATA write then stores a guest-controlled dword at acc[4+], overflowing the 4-element accumulator array. Fix this by resetting next unconditionally in the write handler after calling ati_host_data_flush() or ati_host_data_finish(), and removing the reset from inside ati_host_data_flush(). This ensures the write handler owns the full lifecycle of the accumulator index regardless of flush success or failure. Cc: qemu-stable@nongnu.org Reported-by: Feifan Qian <bea1e@proton.me> Resolves: https://lore.kernel.org/qemu-devel/Czyl6yVfL6sHl_o1kRk8N_LpwXMMRVhO9vgz1qCVJFagn9D4nHSKuiux39iOLty0Q3acxQq_FeovPhTQvSKus2htwjI9lTajLZmqovr0Wxs=@proton.me/ Signed-off-by: Junjie Cao <junjie.cao@intel.com> Reviewed-by: Chad Jablonski <chad@jablonski.xyz> Message-ID: <20260519023937.439077-2-junjie.cao@intel.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>

Junjie Cao committed May 19, 2026 at 10:39 UTC 3565faa0ace1f258789aafaf440ab55c3419df60
2 files changed +2 -1
hw/display/ati.c
+2
@@ -1034,8 +1034,10 @@ static void ati_mm_write(void *opaque, hwaddr addr,
1034 s->host_data.acc[s->host_data.next++] = data;
1035 if (addr == HOST_DATA_LAST) {
1036 ati_host_data_finish(s);
1037 + s->host_data.next = 0;
1038 } else if (s->host_data.next >= 4) {
1039 ati_host_data_flush(s);
1040 + s->host_data.next = 0;
1041 }
1042 break;
1043 default:
hw/display/ati_2d.c
-1
@@ -452,7 +452,6 @@ bool ati_host_data_flush(ATIVGAState *s)
452 }
453
454 /* Track state of the overall blit for use by the next flush */
455 - s->host_data.next = 0;
455 s->host_data.row = row;
456 s->host_data.col = col;
457 if (s->host_data.row >= ctx.dst.height) {