On Aug  1 10:00, Corinna Vinschen wrote:
> On Jul 31 14:05, Jeremy Drake via Cygwin-patches wrote:
> > 3) running from dynamically loaded DLL's startup
> >   newu would contain values from exe's startup, not zero, so would always
> >   write the new pointers to cxx_malloc, memory corruption.
> 
> Ah, ok, but then again, in this case a check against the actual version
> instead of checking just against != 0 should do it, shouldn't it?
> 
> E.g.
> 
>   new_dll_with_additional_operators = newu->api_major != 0
>                                       || newu->api_minor >= 359;
> 
> That should be rewritten to a version check macro eventually, but
> it would disable wrapping the new functions depending on the
> executable being too old, even if the just loaded DLL is new enough.
> But that should be ok.  Better than crashing methinks.

Like this:

diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 69c233c24759..a272208139ab 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -724,6 +724,14 @@ dll_crt0_0 ()
   lock_process::init ();
   user_data->impure_ptr = _impure_ptr;
   user_data->impure_ptr_ptr = &_impure_ptr;
+  /* DLL version info is used by newer _cygwin_crt0_common to handle
+     certain issues in a forward compatible way.  _cygwin_crt0_common
+     overwrites these values with the application's version info at the
+     time of building the app, as usual. */
+  user_data->dll_major = cygwin_version.dll_major;
+  user_data->dll_minor = cygwin_version.dll_minor;
+  user_data->api_major = cygwin_version.api_major;
+  user_data->api_minor = cygwin_version.api_minor;
 
   DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
                   GetCurrentProcess (), &hMainThread,
diff --git a/winsup/cygwin/include/cygwin/version.h 
b/winsup/cygwin/include/cygwin/version.h
index f3321020f72e..00eedeb27ab4 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -36,6 +36,9 @@ details. */
 #define CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS \
   (CYGWIN_VERSION_USER_API_VERSION_COMBINED >= 272)
 
+#define CYGWIN_VERSION_CHECK_FOR_CXX17_OVERLOADS(u) \
+  (CYGWIN_VERSION_PER_PROCESS_API_VERSION_COMBINED (u) >= 359)
+
 /* API_MAJOR 0.0: Initial version.  API_MINOR changes:
     1: Export cygwin32_ calls as cygwin_ as well.
     2: Export j1, jn, y1, yn.
diff --git a/winsup/cygwin/lib/_cygwin_crt0_common.cc 
b/winsup/cygwin/lib/_cygwin_crt0_common.cc
index 5900e6315dbe..312cba5756c0 100644
--- a/winsup/cygwin/lib/_cygwin_crt0_common.cc
+++ b/winsup/cygwin/lib/_cygwin_crt0_common.cc
@@ -124,6 +124,9 @@ _cygwin_crt0_common (MainFunc f, per_process *u)
 {
   per_process *newu = (per_process *) cygwin_internal (CW_USER_DATA);
   bool uwasnull;
+  bool new_dll_with_additional_operators =
+       newu ? CYGWIN_VERSION_CHECK_FOR_CXX17_OVERLOADS (newu)
+            : false;
 
   /* u is non-NULL if we are in a DLL, and NULL in the main exe.
      newu is the Cygwin DLL's internal per_process and never NULL.  */
@@ -190,18 +193,21 @@ _cygwin_crt0_common (MainFunc f, per_process *u)
       CONDITIONALLY_OVERRIDE(oper_new___nt);
       CONDITIONALLY_OVERRIDE(oper_delete_nt);
       CONDITIONALLY_OVERRIDE(oper_delete___nt);
-      CONDITIONALLY_OVERRIDE(oper_delete_sz);
-      CONDITIONALLY_OVERRIDE(oper_delete___sz);
-      CONDITIONALLY_OVERRIDE(oper_new_al);
-      CONDITIONALLY_OVERRIDE(oper_new___al);
-      CONDITIONALLY_OVERRIDE(oper_delete_al);
-      CONDITIONALLY_OVERRIDE(oper_delete___al);
-      CONDITIONALLY_OVERRIDE(oper_delete_sz_al);
-      CONDITIONALLY_OVERRIDE(oper_delete___sz_al);
-      CONDITIONALLY_OVERRIDE(oper_new_al_nt);
-      CONDITIONALLY_OVERRIDE(oper_new___al_nt);
-      CONDITIONALLY_OVERRIDE(oper_delete_al_nt);
-      CONDITIONALLY_OVERRIDE(oper_delete___al_nt);
+      if (new_dll_with_additional_operators)
+       {
+         CONDITIONALLY_OVERRIDE(oper_delete_sz);
+         CONDITIONALLY_OVERRIDE(oper_delete___sz);
+         CONDITIONALLY_OVERRIDE(oper_new_al);
+         CONDITIONALLY_OVERRIDE(oper_new___al);
+         CONDITIONALLY_OVERRIDE(oper_delete_al);
+         CONDITIONALLY_OVERRIDE(oper_delete___al);
+         CONDITIONALLY_OVERRIDE(oper_delete_sz_al);
+         CONDITIONALLY_OVERRIDE(oper_delete___sz_al);
+         CONDITIONALLY_OVERRIDE(oper_new_al_nt);
+         CONDITIONALLY_OVERRIDE(oper_new___al_nt);
+         CONDITIONALLY_OVERRIDE(oper_delete_al_nt);
+         CONDITIONALLY_OVERRIDE(oper_delete___al_nt);
+       }
       /* Now update the resulting set into the global redirectors.  */
       *newu->cxx_malloc = __cygwin_cxx_malloc;
     }

Reply via email to