From 179cec1d2f919d8d8096d6030b0ad9b6285dfd4d Mon Sep 17 00:00:00 2001 From: Bryce Harrington Date: Mon, 23 Mar 2009 14:25:18 -0700 Subject: [PATCH] Check null pointers to not crash on keyrepeat with Xinerama LP: (#324465) With -nvidia, when using Xinerama, holding down a key in a text field on a non-primary screen can cause an X crash. This is caused because the MIPOINTER(pDev) can return a NULL pointer for a non-null pDev in some cases, and the mipointer.c code lacks checks for this condition. MIPOINTER() is a macro #defined locally to mipointer.c, which calls into dixLookupPrivate(), a routine which returns NULL in at least some circumstances - such as if the memory could not be xcalloc'd for whatever reason. Hopefully upstream can provide a better fix for this, but for now it seems reasonable to check the return values of this macro for NULL before usage, as a minimum. Signed-off-by: Bryce Harrington --- mi/mipointer.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 files changed, 36 insertions(+), 2 deletions(-) diff --git a/mi/mipointer.c b/mi/mipointer.c index e37316e..ed0c48c 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -140,6 +140,10 @@ miPointerCloseScreen (int index, ScreenPtr pScreen) if (DevHasCursor(pDev)) { pPointer = MIPOINTER(pDev); + if (pPointer == NULL) { + ErrorF("miPointerCloseScreen: Invalid input device pointer\n"); + return FALSE; + } if (pScreen == pPointer->pScreen) pPointer->pScreen = 0; @@ -192,6 +196,10 @@ miPointerDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) return FALSE; pPointer = MIPOINTER(pDev); + if (pPointer == NULL) { + ErrorF("miPointerDisplayCursor: Invalid input device pointer\n"); + return FALSE; + } pPointer->pCursor = pCursor; pPointer->pScreen = pScreen; @@ -205,6 +213,10 @@ miPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox) miPointerPtr pPointer; pPointer = MIPOINTER(pDev); + if (pPointer == NULL) { + ErrorF("miPointerConstrainCursor: Invalid input device pointer\n"); + return FALSE; + } pPointer->limits = *pBox; pPointer->confined = PointerConfinedToScreen(pDev); @@ -304,6 +316,11 @@ miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) BOOL changedScreen = FALSE; pPointer = MIPOINTER(pDev); + if (pPointer == NULL) { + ErrorF("miPointerWarpCursor: Invalid input device pointer\n"); + return; + } + SetupScreen (pScreen); if (pPointer->pScreen != pScreen) @@ -366,6 +383,10 @@ miPointerUpdateSprite (DeviceIntPtr pDev) return; pPointer = MIPOINTER(pDev); + if (pPointer == NULL) { + ErrorF("miPointerUpdateSprite: Invalid input device pointer\n"); + return; + } pScreen = pPointer->pScreen; if (!pScreen) @@ -433,13 +454,17 @@ miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y) ScreenPtr pScreen; miPointerPtr pPointer; - pPointer = MIPOINTER(pDev); - pScreen = screenInfo.screens[screen_no]; pScreenPriv = GetScreenPrivate (pScreen); (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE); NewCurrentScreen (pDev, pScreen, x, y); + pPointer = MIPOINTER(pDev); + if (pPointer == NULL) { + ErrorF("miPointerSetScreen: Invalid input device pointer\n"); + return; + } + pPointer->limits.x2 = pScreen->width; pPointer->limits.y2 = pScreen->height; } @@ -475,6 +500,10 @@ miPointerMoved (DeviceIntPtr pDev, ScreenPtr pScreen, SetupScreen(pScreen); pPointer = MIPOINTER(pDev); + if (pPointer == NULL) { + ErrorF("miPointerMoved: Invalid input device pointer\n"); + return; + } /* Hack: We mustn't call into ->MoveCursor for anything but the * VCP, as this may cause a non-HW rendered cursor to be rendered during @@ -504,6 +533,11 @@ miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y) miPointerPtr pPointer; pPointer = MIPOINTER(pDev); + if (pPointer == NULL) { + ErrorF("miPointerSetPosition: Invalid input device pointer\n"); + return; + } + pScreen = pPointer->pScreen; if (!pScreen) return; /* called before ready */ -- 1.6.0.4