From 356c2eadf4c9d2f3991ea4a48df8507fde817c18 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 6 Jan 2017 00:32:06 -0800 Subject: [PATCH] Fixed bug 3544 - Memory freeing bug in SDL_DestroyRenderer/SDL_DestroyTexture felix Here's a snippet of SDL_DestroyRenderer from hg revision 10746:7540ff5d0e0e: SDL_Texture *texture = NULL; SDL_Texture *nexttexture = NULL; /* ... */ for (texture = renderer->textures; texture; texture = nexttexture) { nexttexture = texture->next; SDL_DestroyTexture(texture); } SDL_DestroyTexture removes the texture from the linked list pointed to by the renderer and ends up calling SDL_DestroyTextureInternal, which contains this: if (texture->native) { SDL_DestroyTexture(texture->native); } If it happens that texture->native is an alias of nexttexture two stack frames up, SDL_DestroyRenderer will end up trying to destroy an already freed texture. I've had this very situation happen in dosemu2. Bug introduced in revision 10650:a8253d439914, which has a somewhat ironic description of "Fixed all known static analysis bugs"... --- src/render/SDL_render.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 4a4828b8e..4b8845931 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -1951,11 +1951,9 @@ SDL_DestroyRenderer(SDL_Renderer * renderer) /* Free existing textures for this renderer */ SDL_SetRenderTarget(renderer, NULL); - for (texture = renderer->textures; texture; texture = nexttexture) { - nexttexture = texture->next; - SDL_DestroyTexture(texture); + while (renderer->textures) { + SDL_DestroyTexture(renderer->textures); } - renderer->textures = NULL; if (renderer->window) { SDL_SetWindowData(renderer->window, SDL_WINDOWRENDERDATA, NULL);