On 7/13/20 2:45 PM, Gerd Hoffmann wrote: > Calling ramfb_display_update() might replace the DisplaySurface with the > boot display, which in turn will free the currently active > DisplaySurface. > > So clear our DisplaySurface pinter (dpy->region.surface pointer) to (a) > avoid use-after-free and (b) force replacing the boot display with the > real display when switching back. > > Signed-off-by: Gerd Hoffmann <kra...@redhat.com> > --- > hw/vfio/display.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/hw/vfio/display.c b/hw/vfio/display.c > index a57a22674d62..342054193b3c 100644 > --- a/hw/vfio/display.c > +++ b/hw/vfio/display.c > @@ -405,6 +405,7 @@ static void vfio_display_region_update(void *opaque) > if (!plane.drm_format || !plane.size) { > if (dpy->ramfb) { > ramfb_display_update(dpy->con, dpy->ramfb); > + dpy->region.surface = NULL; > } > return; > } >
More generic fix: -- >8 -- --- a/ui/console.c +++ b/ui/console.c @@ -1580,10 +1580,10 @@ void dpy_gfx_replace_surface(QemuConsole *con, DisplaySurface *surface) { DisplayState *s = con->ds; - DisplaySurface *old_surface = con->surface; + QemuConsole *old_con = con; DisplayChangeListener *dcl; - assert(old_surface != surface || surface == NULL); + assert(con->surface != surface || surface == NULL); con->surface = surface; QLIST_FOREACH(dcl, &s->listeners, next) { @@ -1594,7 +1594,8 @@ void dpy_gfx_replace_surface(QemuConsole *con, dcl->ops->dpy_gfx_switch(dcl, surface); } } - qemu_free_displaysurface(old_surface); + qemu_free_displaysurface(old_con->surface); + old_con->surface = NULL; } ---