[PATCH 04/19] qxl_driver: hide cursors on vt switch

Alon Levy alevy at redhat.com
Thu May 31 03:24:38 PDT 2012


This is not enough to prevent any qxl_destroy_pixmap call during vt
switch, but it prevents those triggered by CursorDisplayCursor.

Note: a matching xf86_show_cursors call doesn't hurt, but is not
required, so not adding it.

It is still possible to access freed memory by the following trigger:

==4416== Invalid read of size 8
==4416==    at 0x5D15EC1: unlink_surface (qxl_surface.c:685)
==4416==    by 0x5D162F9: qxl_surface_kill (qxl_surface.c:799)
==4416==    by 0x5D12688: qxl_destroy_pixmap (qxl_driver.c:928)
==4416==    by 0x55730B: damageDestroyPixmap (damage.c:1556)
==4416==    by 0x51C77B: ShmDestroyPixmap (shm.c:273)
==4416==    by 0x54591B: FreePicture (picture.c:1465)
==4416==    by 0x467A32: doFreeResource (resource.c:873)
==4416==    by 0x467B7E: FreeResource (resource.c:903)
==4416==    by 0x547742: ProcRenderFreePicture (render.c:661)
==4416==    by 0x54B13A: ProcRenderDispatch (render.c:1988)
==4416==    by 0x430670: Dispatch (dispatch.c:428)
==4416==    by 0x492604: main (main.c:288)
==4416==  Address 0x121031e0 is 116,960 bytes inside a block of size 122,880 free'd
==4416==    at 0x4A079AE: free (vg_replace_malloc.c:427)
==4416==    by 0x5D16BDA: qxl_surface_cache_evacuate_all (qxl_surface.c:1060)
==4416==    by 0x5D13078: qxl_leave_vt (qxl_driver.c:1209)
==4416==    by 0x4A4D4F: xf86VTSwitch (xf86Events.c:462)
==4416==    by 0x4A4926: xf86Wakeup (xf86Events.c:285)
==4416==    by 0x43E2E1: WakeupHandler (dixutils.c:421)
==4416==    by 0x488A75: WaitForSomething (WaitFor.c:224)
==4416==    by 0x4303CF: Dispatch (dispatch.c:357)
==4416==    by 0x492604: main (main.c:288)

This is fixed by a following patch to not free all_surfaces, instead
keeping pointers from it to the evacuated list.
---
 src/qxl_driver.c |   14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index f7ccbbf..a765c9f 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -38,6 +38,9 @@
 #include <errno.h>
 #include <time.h>
 #include <stdlib.h>
+
+#include <xf86Crtc.h>
+
 #include "qxl.h"
 #include "assert.h"
 #include "qxl_option_helpers.h"
@@ -1187,7 +1190,7 @@ qxl_enter_vt(int scrnIndex, int flags)
     }
 
     pScrn->EnableDisableFBAccess (scrnIndex, TRUE);
-    
+
     return TRUE;
 }
 
@@ -1197,6 +1200,8 @@ qxl_leave_vt(int scrnIndex, int flags)
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     qxl_screen_t *qxl = pScrn->driverPrivate;
     
+    xf86_hide_cursors (pScrn);
+
     pScrn->EnableDisableFBAccess (scrnIndex, FALSE);
 
     qxl->vt_surfaces = qxl_surface_cache_evacuate_all (qxl->surface_cache);
@@ -1385,6 +1390,10 @@ static void qxl_add_mode(ScrnInfoPtr pScrn, int width, int height, int type)
     xf86ModesAdd(pScrn->monitor->Modes, mode);
 }
 
+static const xf86CrtcConfigFuncsRec qxl_xf86crtc_config_funcs = {
+        NULL
+};
+
 static Bool
 qxl_pre_init(ScrnInfoPtr pScrn, int flags)
 {
@@ -1517,7 +1526,10 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
     
     CHECK_POINT();
     
+    xf86CrtcConfigInit(pScrn, &qxl_xf86crtc_config_funcs);
+
     xf86PruneDriverModes(pScrn);
+
     pScrn->currentMode = pScrn->modes;
     /* If no modes are specified in xorg.conf, default to 1024x768 */
     if (pScrn->display->modes == NULL || pScrn->display->modes[0] == NULL)
-- 
1.7.10.1



More information about the xorg-devel mailing list