https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=cb33699b031f5b716b4b9522b88275ebf41210d0

commit cb33699b031f5b716b4b9522b88275ebf41210d0
Author:     Corinna Vinschen <cori...@vinschen.de>
AuthorDate: Wed Jul 2 22:18:50 2025 +0200
Commit:     Corinna Vinschen <cori...@vinschen.de>
CommitDate: Thu Jul 3 12:36:15 2025 +0200

    Cygwin: dlsym: fetch module list via EnumProcessModules
    
    We're using RtlQueryProcessDebugInformation from dlsym since
    commit 31ddf45dd8694 ("* autoload.cc (EnumProcessModules): Remove.")
    
    Observations on the Cygwin mailing list show that calling
    RtlQueryProcessDebugInformation on a process is neither
    thread-safe, nor multi-process-safe, see
    https://cygwin.com/pipermail/cygwin/2025-July/258403.html
    for details.
    
    This patch essentially reverts 31ddf45dd8694.  Fetch the list of
    loaded modules in the current process by calling EnumProcessModules
    again.
    
    Reported-by: Christian Franke <christian.fra...@t-online.de>
    Fixes: 31ddf45dd8694 ("* autoload.cc (EnumProcessModules): Remove.")
    Signed-off-by: Corinna Vinschen <cori...@vinschen.de>

Diff:
---
 winsup/cygwin/autoload.cc |  2 ++
 winsup/cygwin/dlfcn.cc    | 35 +++++++++++------------------------
 2 files changed, 13 insertions(+), 24 deletions(-)

diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 35b207e9daf3..d5d344d21dd4 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -525,6 +525,8 @@ LoadDLLfunc (CoInitialize, ole32)
 LoadDLLfunc (CoUninitialize, ole32)
 LoadDLLfunc (CoTaskMemFree, ole32)
 
+LoadDLLfunc (EnumProcessModules, psapi)
+
 LoadDLLfunc (LsaConnectUntrusted, secur32)
 LoadDLLfunc (LsaDeregisterLogonProcess, secur32)
 LoadDLLfunc (LsaFreeReturnBuffer, secur32)
diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc
index 9b6bb55b34a3..e06616d7fa77 100644
--- a/winsup/cygwin/dlfcn.cc
+++ b/winsup/cygwin/dlfcn.cc
@@ -7,6 +7,7 @@ Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 details. */
 
 #include "winsup.h"
+#include <psapi.h>
 #include <stdlib.h>
 #include <dlfcn.h>
 #include <ctype.h>
@@ -318,32 +319,18 @@ dlsym (void *handle, const char *name)
 
   if (handle == RTLD_DEFAULT)
     { /* search all modules */
-      PDEBUG_BUFFER buf;
-      NTSTATUS status;
+      HMODULE *modules;
+      tmp_pathbuf tp;
+      DWORD size;
 
-      buf = RtlCreateQueryDebugBuffer (0, FALSE);
-      if (!buf)
-       {
-         set_errno (ENOMEM);
-         set_dl_error ("dlsym");
-         return NULL;
-       }
-      status = RtlQueryProcessDebugInformation (GetCurrentProcessId (),
-                                               PDI_MODULES, buf);
-      if (!NT_SUCCESS (status))
-       __seterrno_from_nt_status (status);
+      modules = (HMODULE *) tp.w_get ();
+      if (!EnumProcessModules (GetCurrentProcess (), modules,
+                              2 * NT_MAX_PATH, &size))
+       __seterrno ();
       else
-       {
-         PDEBUG_MODULE_ARRAY mods = (PDEBUG_MODULE_ARRAY)
-                                    buf->ModuleInformation;
-         for (ULONG i = 0; i < mods->Count; ++i)
-           if ((ret = (void *)
-                      GetProcAddress ((HMODULE) mods->Modules[i].Base, name)))
-             break;
-         if (!ret)
-           set_errno (ENOENT);
-       }
-      RtlDestroyQueryDebugBuffer (buf);
+       for (uint32_t i = 0; i < size / sizeof (HMODULE); ++i)
+         if ((ret = (void *) GetProcAddress (modules[i], name)))
+           break;
     }
   else
     {

Reply via email to