On 2026/08/27 19:36, Marc-André Lureau wrote:
Hi

On Thu, Aug 27, 2026 at 2:31 PM Daniel P. Berrangé <[email protected]> wrote:

On Thu, Aug 27, 2026 at 01:58:14PM +0400, Marc-André Lureau wrote:
Hi

On Thu, Aug 27, 2026 at 12:47 PM Daniel P. Berrangé <[email protected]> wrote:

On Thu, Aug 27, 2026 at 11:06:47AM +0400, [email protected] wrote:
From: Marc-André Lureau <[email protected]>

When the new cursor is the same object as the one already held by
the console and the refcount is 1, cursor_unref frees it before
cursor_ref can increment the count.

Ref the incoming cursor before unreffing the old one so the
refcount goes 1-2-1 instead of 1-0 (freed) then use-after-free.

I don't see where/how this can happen.  The caller of
qemu_console_set_cursor should own its own reference
on 'cursor'. So on entry to this method, 'cursor'
should have a ref of 2 if it is the same as the
current con->cursor.

if anything the behaviour you describe sounds like a
bug in a caller not holding its own reference.

You are right, I thought virtio-gpu kept a weak pointer, but it should
have a strong ref, so we should never reach 0. I can't explain the
crash I observed then.

Is there a bug report for this or crash scenario info ?

No, I just had this report from ASAN when testing -display dbus with
virtio-gpu. Pretty regular test.

dbus_cursor_define() looks suspici

> @data is not modified by this function and must remain valid with an
> unchanging value until such a time as @notify is called with
> @user_data. ous; it exposes mutable cursor pixels through a zero-copy GVariant and arranges for cursor_unref() to run when that variant is destroyed.

The documentation of g_dbus_connection_add_filter() says "filters are run in a dedicated message handling thread", but QEMUCursor::refcount uses unsynchronized ++/--, which may explain your ASAN crash.

Meanwhile, virtio-gpu repeatedly mutates the same cursor, which violates g_variant_new_from_data()’s requirement that its bytes remain unchanged until notification. Its documentation says "if the contents of @data change before that time then the result is undefined."

Regards,
Akihiko Odaki


Something wrong with the 'cursor' object stored in virtio_gpu_scanout ?
I notice in the VMState:

         VMSTATE_UINT32(cursor.resource_id, struct virtio_gpu_scanout),
         VMSTATE_UINT32(cursor.hot_x, struct virtio_gpu_scanout),
         VMSTATE_UINT32(cursor.hot_y, struct virtio_gpu_scanout),
         VMSTATE_UINT32(cursor.pos.x, struct virtio_gpu_scanout),
         VMSTATE_UINT32(cursor.pos.y, struct virtio_gpu_scanout),

what is restoring the "refcount" to "1" when vmstate is loaded ?

cursor != current_cursor (allocated with update_cursor on post_load)


Reply via email to