diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2015-09-17 16:04:33 -0700 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2015-10-26 12:18:46 -0400 |
commit | 49d04a43360267fb7cbbeec0ea4985ba224fb59c (patch) | |
tree | 0a3917419e8d5d86a59671dca1cd2a998da0e57a | |
parent | daf15b551631e8a98960e629039bef1880de8f82 (diff) |
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>
(cherry picked from commit 82eb490b0a341729f25d0c42a937fe29d99da521)
-rw-r--r-- | dix/main.c | 1 | ||||
-rw-r--r-- | dix/privates.c | 9 |
2 files changed, 10 insertions, 0 deletions
diff --git a/dix/main.c b/dix/main.c index 09f9504b8..7c6ac943f 100644 --- a/dix/main.c +++ b/dix/main.c @@ -337,6 +337,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); diff --git a/dix/privates.c b/dix/privates.c index e03b2255b..969d0141c 100644 --- a/dix/privates.c +++ b/dix/privates.c @@ -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 */ |