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

commit 70026ace15f0ad65f9fe7af01285c921c5f3e91f
Author:     Corinna Vinschen <cori...@vinschen.de>
AuthorDate: Sun Mar 30 20:09:02 2025 +0200
Commit:     Corinna Vinschen <cori...@vinschen.de>
CommitDate: Sun Mar 30 20:57:00 2025 +0200

    Cygwin: dlfcn: avoid ENOENT on dlcose after dlopen(cygwin1.dll)
    
    When dlopen'ing the Cygwin DLL, refcounting the number of dlopen
    calls  fails because dll_list::find returns NULL if the address
    resolves to the Cygwin DLL.
    
    Fix this by adding a bool parameter to dll_list::find which allows
    find to return the dll entry for the Cygwin DLL for the sake of
    dlopen/dlclose/fork.
    
    Fixes: 33297d810d90 ("Cygwin: dlfcn: Fix reference counting")
    Signed-off-by: Corinna Vinschen <cori...@vinschen.de>
    
    (cherry picked from commit 82b31085f6ad23c3aaf5a928bd56fe06cbe63df5)

Diff:
---
 winsup/cygwin/dlfcn.cc                  | 4 ++--
 winsup/cygwin/dll_init.cc               | 4 ++--
 winsup/cygwin/local_includes/dll_init.h | 2 +-
 winsup/cygwin/release/3.6.1             | 3 +++
 4 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc
index fb705247352e..f98c7db475f7 100644
--- a/winsup/cygwin/dlfcn.cc
+++ b/winsup/cygwin/dlfcn.cc
@@ -276,7 +276,7 @@ dlopen (const char *name, int flags)
       /* reference counting */
       if (ret)
        {
-         dll *d = dlls.find (ret);
+         dll *d = dlls.find (ret, true);
          if (d)
            ++d->count;
        }
@@ -349,7 +349,7 @@ dlclose (void *handle)
   if (handle != GetModuleHandle (NULL))
     {
       /* reference counting */
-      dll *d = dlls.find (handle);
+      dll *d = dlls.find (handle, true);
       if (!d || d->count <= 0)
        {
          errno = ENOENT;
diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc
index 1a047511f8cc..c6fb94a43379 100644
--- a/winsup/cygwin/dll_init.cc
+++ b/winsup/cygwin/dll_init.cc
@@ -542,7 +542,7 @@ dll_list::topsort_visit (dll* d, bool seek_tail)
 
 
 dll *
-dll_list::find (void *retaddr)
+dll_list::find (void *retaddr, bool find_self)
 {
   MEMORY_BASIC_INFORMATION m;
   if (!VirtualQuery (retaddr, &m, sizeof m))
@@ -551,7 +551,7 @@ dll_list::find (void *retaddr)
 
   dll *d = &start;
   while ((d = d->next))
-    if (d->type != DLL_SELF && d->handle == h)
+    if ((d->type != DLL_SELF || find_self) && d->handle == h)
       break;
   return d;
 }
diff --git a/winsup/cygwin/local_includes/dll_init.h 
b/winsup/cygwin/local_includes/dll_init.h
index 65f4213dbb7a..f79b1573ee09 100644
--- a/winsup/cygwin/local_includes/dll_init.h
+++ b/winsup/cygwin/local_includes/dll_init.h
@@ -131,7 +131,7 @@ public:
   int reload_on_fork;
   dll *operator [] (PCWCHAR ntname);
   dll *alloc (HINSTANCE, per_process *, dll_type);
-  dll *find (void *);
+  dll *find (void *, bool = false);
   void detach (void *);
   void init ();
   void load_after_fork (HANDLE);
diff --git a/winsup/cygwin/release/3.6.1 b/winsup/cygwin/release/3.6.1
index 95c2c054e9ea..85c3f6c0554b 100644
--- a/winsup/cygwin/release/3.6.1
+++ b/winsup/cygwin/release/3.6.1
@@ -15,3 +15,6 @@ Fixes:
   in the SA_ONSTACK case, because locally-copied context on the normal
   stack area is not accessible from the signal handler.
   Addresses: https://cygwin.com/pipermail/cygwin/2025-March/257714.html
+
+- Fix reference counting when dlopen/dlclose is called on the Cygwin DLL.
+  Addresses: https://cygwin.com/pipermail/cygwin/2025-March/257783.html

Reply via email to