[vlc-devel] [PATCH 2/2] win32: fix use-after-free at thread end

RĂ©mi Denis-Courmont remi at remlab.net
Sun Sep 6 19:12:26 CEST 2020


Use FreeLibraryAndExitThread() instead of ExitThread() as Win32 does
not natively support non-detached threads. This fixes a race condition
when LibVLC is unloaded (see also MSDN on FreeLibraryAndExitThread()).
---
 src/win32/thread.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/src/win32/thread.c b/src/win32/thread.c
index cd15828128..e7f2ee27d3 100644
--- a/src/win32/thread.c
+++ b/src/win32/thread.c
@@ -56,6 +56,7 @@ static DWORD thread_key;
 struct vlc_thread
 {
     HANDLE         id;
+    HMODULE        lib;
 
     bool           killable;
     atomic_bool    killed;
@@ -348,14 +349,12 @@ static void vlc_thread_destroy(vlc_thread_t th)
 
 static noreturn void vlc_thread_exit(vlc_thread_t self)
 {
+    HMODULE lib = self->lib;
+
     if (self->id == NULL) /* Detached thread */
         vlc_thread_destroy(self);
 
-#if VLC_WINSTORE_APP
-    ExitThread(0);
-#else // !VLC_WINSTORE_APP
-    _endthreadex(0);
-#endif // !VLC_WINSTORE_APP
+    FreeLibraryAndExitThread(lib, 0);
 }
 
 static
@@ -381,6 +380,14 @@ static int vlc_clone_attr (vlc_thread_t *p_handle, bool detached,
     struct vlc_thread *th = malloc (sizeof (*th));
     if (unlikely(th == NULL))
         return ENOMEM;
+
+    if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+                           (const void *)vlc_entry, &th->lib))
+    {
+        free(th);
+        return ENOBUFS;
+    }
+
     th->entry = entry;
     th->data = data;
     th->killable = false; /* not until vlc_entry() ! */
@@ -402,6 +409,7 @@ static int vlc_clone_attr (vlc_thread_t *p_handle, bool detached,
     if (h == 0)
     {
         int err = errno;
+        FreeLibrary(th->lib);
         free (th);
         return err;
     }
-- 
2.28.0



More information about the vlc-devel mailing list