Bogus screen updates
cover Bogus screen updates
The PVFB frontend can get confused and send a bogus screen update to the back end when the screen is clean.
Two parts: fix the frontend not to do that, and fix the backend not to choke on it.
PATCH 1/2 PVFB frontend can send bogus screen updates
The PVFB frontend can get confused and send a screen update to the backend when the screen is actually clean. Such an update asks for the impossible rectangle (x1, x2, y1, y2) = (INT_MAX, 0, INT_MAX, 0). Fix by setting the dirty flag in the obvious place: when the dirty rectangle is grown.
drivers/xen/fbfront/xenfb.c +6 -1
@@ -201,6 +201,11 @@ static void xenfb_update_screen(struct xmutex_unlock (&info->mm_lock); +if (x2 < x1 || y2 < y1) { +printk ("xenfb_update_screen bogus rect %d %d %d %d\n" , + x1, x2, y1, y2); +WARN_ON (1 ); + }xenfb_do_update (info, x1, y1, x2 - x1, y2 - y1); }
@@ -252,7 +257,6 @@ static void xenfb_timer(unsigned long dastatic void xenfb_timer (unsigned long data) {struct xenfb_info *info = (struct xenfb_info *)data; - info->dirty =1 ;wake_up (&info->wq); }
@@ -272,6 +276,7 @@ static void __xenfb_refresh(struct xenfb info->x1 = x1;if (info->x2 < x2) info->x2 = x2; + info->dirty =1 ;if (timer_pending (&info->refresh))return ;
PATCH 2/2 PVFB SDL backend chokes on bogus screen updates
In reply to Markus ArmbrusterBogus screen update requests from buggy or malicous frontend make SDL crash. The VNC backend silently ignores them. Catch and log them.
tools/ioemu/hw/xenfb.c +18 -3
@@ -488,12 +488,27 @@ static void xenfb_on_fb_event(struct xenrmb ();/* ensure we see ring contents up to prod */ for (cons = page->out_cons; cons != prod; cons++) {union xenfb_out_event *event = &XENFB_OUT_RING_REF (page, cons); +int x, y, w, h;switch (event->type) {case XENFB_TYPE_UPDATE : -xenfb_guest_copy (xenfb, - event->update.x, event->update.y, - event->update.width, event->update.height); + x =MAX (event->update.x,0 ); + y =MAX (event->update.y,0 ); + w =MIN (event->update.width, xenfb->width - x); + h =MIN (event->update.height, xenfb->height - y); +if (w <0 || h <0 ) { +fprintf (stderr,"%s bogus update ignored\n" , + xenfb->fb.nodename); +break ; + } +if (x != event->update.x || y != event->update.y + || w != event->update.width + || h != event->update.height) { +fprintf (stderr,"%s bogus update clipped\n" , + xenfb->fb.nodename); +break ; + } +xenfb_guest_copy (xenfb, x, y, w, h);break ; } }