Merge branch 'dbe' into 'master'

dbe: Fix use-after-free when closing (or resetting) the server

See merge request xorg/xserver!589
This commit is contained in:
Peter Harris 2025-12-11 17:47:57 +00:00
commit d9e2ebe86f
2 changed files with 22 additions and 18 deletions

View file

@ -1203,7 +1203,7 @@ DbeWindowPrivDelete(void *pDbeWinPriv, XID id)
/****************************************************************************** /******************************************************************************
* *
* DBE DIX Procedure: DbeResetProc * DBE DIX Procedure: DbeCloseScreen
* *
* Description: * Description:
* *
@ -1212,25 +1212,24 @@ DbeWindowPrivDelete(void *pDbeWinPriv, XID id)
* other tasks related to shutting down the extension. * other tasks related to shutting down the extension.
* *
*****************************************************************************/ *****************************************************************************/
static void static Bool
DbeResetProc(ExtensionEntry * extEntry) DbeCloseScreen(ScreenPtr pScreen)
{ {
int i; DbeScreenPrivPtr pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
ScreenPtr pScreen;
DbeScreenPrivPtr pDbeScreenPriv;
for (i = 0; i < screenInfo.numScreens; i++) {
pScreen = screenInfo.screens[i];
pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
if (pDbeScreenPriv) { if (pDbeScreenPriv) {
/* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit(). */ /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit(). */
pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow; pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
pScreen->PositionWindow = pDbeScreenPriv->PositionWindow; pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
pScreen->CloseScreen = pDbeScreenPriv->CloseScreen;
free(pDbeScreenPriv); free(pDbeScreenPriv);
dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, NULL);
return pScreen->CloseScreen(pScreen);
} }
}
} /* DbeResetProc() */ /* CloseScreen was wrapped, but there is no nested function to call */
return FALSE;
} /* DbeCloseScreen() */
/****************************************************************************** /******************************************************************************
* *
@ -1400,6 +1399,10 @@ DbeExtensionInit(void)
pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow; pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
pScreen->DestroyWindow = DbeDestroyWindow; pScreen->DestroyWindow = DbeDestroyWindow;
/* Wrap CloseScreen, to clean up */
pDbeScreenPriv->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = DbeCloseScreen;
} }
else { else {
/* DDX initialization failed. Stub the screen. */ /* DDX initialization failed. Stub the screen. */
@ -1427,7 +1430,7 @@ DbeExtensionInit(void)
/* Now add the extension. */ /* Now add the extension. */
extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents, extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents,
DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch, DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch,
DbeResetProc, StandardMinorOpcode); NULL, StandardMinorOpcode);
dbeErrorBase = extEntry->errorBase; dbeErrorBase = extEntry->errorBase;
SetResourceTypeErrorValue(dbeWindowPrivResType, SetResourceTypeErrorValue(dbeWindowPrivResType,

View file

@ -175,6 +175,7 @@ typedef struct _DbeScreenPrivRec {
*/ */
PositionWindowProcPtr PositionWindow; PositionWindowProcPtr PositionWindow;
DestroyWindowProcPtr DestroyWindow; DestroyWindowProcPtr DestroyWindow;
CloseScreenProcPtr CloseScreen;
/* Per-screen DIX routines */ /* Per-screen DIX routines */
Bool (*SetupBackgroundPainter) (WindowPtr /*pWin */ , Bool (*SetupBackgroundPainter) (WindowPtr /*pWin */ ,