From 4834bd26e775181ac744bcc80d537786cca9b63c Mon Sep 17 00:00:00 2001 From: Aidan Foster Date: Mon, 14 Mar 2022 18:51:37 +0000 Subject: [PATCH] Set current thread state to NULL in teardown In the EGL destructor, DestroyThreadState gets called by __eglCurrentTeardown to free the threadState, but the threadState does not get changed to NULL when this happens. The function eglReleaseThread calls __eglDestroyCurrentThreadAPIState, which does set the threadState to NULL, right before calling DestroyThreadState. Both eglReleaseThread and __eglDestroyCurrentThreadAPIState check to make sure the threadState is NULL before continuing. If eglReleaseThread gets externally called after destruction, the threadState is not NULL, so DestroyThreadState will be called to free the threadState that was already freed by the destructor, causing a double free. This change is to add the same setting threadState to NULL in __eglCurrentTeardown as which already __eglDestroyCurrentThreadAPIState, to prevent this double free situation. --- src/EGL/libeglcurrent.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/EGL/libeglcurrent.c b/src/EGL/libeglcurrent.c index b40cabe..e9597d2 100644 --- a/src/EGL/libeglcurrent.c +++ b/src/EGL/libeglcurrent.c @@ -94,7 +94,8 @@ void __eglCurrentTeardown(EGLBoolean doReset) while (!glvnd_list_is_empty(¤tThreadStateList)) { __EGLThreadAPIState *threadState = glvnd_list_first_entry( ¤tThreadStateList, __EGLThreadAPIState, entry); - DestroyThreadState(threadState); + __glvndPthreadFuncs.setspecific(threadStateKey, NULL); + DestroyThreadState(threadState); } if (doReset) {