[newlib-cygwin/main] Cygwin: dlfcn: avoid ENOENT on dlcose after dlopen(cygwin1.dll)

Corinna Vinschen via Cygwin-cvs <[email protected]>
Newsgroups gmane.os.cygwin.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=82b31085f6ad23c3aaf5a928bd56fe06cbe63df5

commit 82b31085f6ad23c3aaf5a928bd56fe06cbe63df5
Author:     Corinna Vinschen <[email protected]>
AuthorDate: Sun Mar 30 20:09:02 2025 +0200
Commit:     Corinna Vinschen <[email protected]>
CommitDate: Sun Mar 30 20:52:34 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 <[email protected]>

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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.