From 4834bd26e775181ac744bcc80d537786cca9b63c Mon Sep 17 00:00:00 2001 From: Aidan Foster Date: Mon, 14 Mar 2022 18:51:37 +0000 Subject: [PATCH 1/3] 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) { From 1f2bfbb6f08bf05b4845864601c8d56d785d4177 Mon Sep 17 00:00:00 2001 From: Aidan Foster Date: Mon, 14 Mar 2022 20:38:20 +0000 Subject: [PATCH 2/3] Update src/EGL/libeglcurrent.c --- src/EGL/libeglcurrent.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EGL/libeglcurrent.c b/src/EGL/libeglcurrent.c index e9597d2..0e55c88 100644 --- a/src/EGL/libeglcurrent.c +++ b/src/EGL/libeglcurrent.c @@ -94,9 +94,9 @@ void __eglCurrentTeardown(EGLBoolean doReset) while (!glvnd_list_is_empty(¤tThreadStateList)) { __EGLThreadAPIState *threadState = glvnd_list_first_entry( ¤tThreadStateList, __EGLThreadAPIState, entry); - __glvndPthreadFuncs.setspecific(threadStateKey, NULL); - DestroyThreadState(threadState); + DestroyThreadState(threadState); } + __glvndPthreadFuncs.setspecific(threadStateKey, NULL); if (doReset) { __glvndPthreadFuncs.mutex_init(¤tStateListMutex, NULL); From 9f59259dc65952d80ca371389def644b7a9914ea Mon Sep 17 00:00:00 2001 From: Aidan Foster Date: Tue, 15 Mar 2022 17:53:15 +0000 Subject: [PATCH 3/3] Moving setspecific to before DestroyThreadState --- src/EGL/libeglcurrent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EGL/libeglcurrent.c b/src/EGL/libeglcurrent.c index 0e55c88..a09b96d 100644 --- a/src/EGL/libeglcurrent.c +++ b/src/EGL/libeglcurrent.c @@ -91,12 +91,12 @@ void __eglCurrentTeardown(EGLBoolean doReset) __eglDestroyAPIState(apiState); } + __glvndPthreadFuncs.setspecific(threadStateKey, NULL); while (!glvnd_list_is_empty(¤tThreadStateList)) { __EGLThreadAPIState *threadState = glvnd_list_first_entry( ¤tThreadStateList, __EGLThreadAPIState, entry); DestroyThreadState(threadState); } - __glvndPthreadFuncs.setspecific(threadStateKey, NULL); if (doReset) { __glvndPthreadFuncs.mutex_init(¤tStateListMutex, NULL);