privates: Clear screen-specific keys during CloseScreen

The modesetting driver corrupts memory when used after a server regeneration
because not enough memory is allocated for its pixmap privates.  This happens
because its call to dixRegisterScreenSpecificPrivateKey() does nothing because
key->initialized is still TRUE from the first server generation.  However, the
key is not in the screen's linked list of screen-specific privates because
that's freed and reallocated during the server generation loop in dix_main().

Fix this by clearing key->initialized before CloseScreen and add a call to
dixFreeScreenSpecificPrivates() for GPU screens.

v2: Just set key->initialized to FALSE and move dixFreeScreenSpecificPrivates()
calls to after CloseScreen.

v3: Move dixFreeScreenSpecificPrivates() calls back to just before CloseScreen.

Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
Aaron Plattner 2015-09-17 16:04:33 -07:00 committed by Adam Jackson
parent 18a93da9b1
commit 82eb490b0a
2 changed files with 10 additions and 0 deletions

View File

@ -339,6 +339,7 @@ dix_main(int argc, char *argv[], char *envp[])
for (i = screenInfo.numGPUScreens - 1; i >= 0; i--) {
ScreenPtr pScreen = screenInfo.gpuscreens[i];
FreeScratchPixmapsForScreen(pScreen);
dixFreeScreenSpecificPrivates(pScreen);
(*pScreen->CloseScreen) (pScreen);
dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
free(pScreen);

View File

@ -642,6 +642,15 @@ dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key,
void
dixFreeScreenSpecificPrivates(ScreenPtr pScreen)
{
DevPrivateType t;
for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) {
DevPrivateKey key;
for (key = pScreen->screenSpecificPrivates[t].key; key; key = key->next) {
key->initialized = FALSE;
}
}
}
/* Initialize screen-specific privates in AddScreen */