This prevents memory corruption if a newer app or dll is used with an
older cygwin dll.  This is an unsupported scenario, but it's still a
good idea to avoid corrupting memory if possible.

Fixes: 7d5c55faa1 ("Cygwin: add wrappers for newer new/delete overloads")
Co-authored-by: Corinna Vinschen <cori...@vinschen.de>
Signed-off-by: Jeremy Drake <cyg...@jdrake.com>
---
 winsup/cygwin/globals.cc                 |  4 +--
 winsup/cygwin/include/cygwin/version.h   |  3 ++
 winsup/cygwin/lib/_cygwin_crt0_common.cc | 38 +++++++++++++-----------
 3 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc
index d8e058f191..86b0c2718a 100644
--- a/winsup/cygwin/globals.cc
+++ b/winsup/cygwin/globals.cc
@@ -173,8 +173,8 @@ extern "C" {
    /* unused */ {},
    /* cxx_malloc */ &default_cygwin_cxx_malloc,
    /* hmodule */ NULL,
-   /* api_major */ 0,
-   /* api_minor */ 0,
+   /* api_major */ CYGWIN_VERSION_API_MAJOR,
+   /* api_minor */ CYGWIN_VERSION_API_MINOR,
    /* unused2 */ {},
    /* posix_memalign */ posix_memalign,
    /* pseudo_reloc_start */ NULL,
diff --git a/winsup/cygwin/include/cygwin/version.h 
b/winsup/cygwin/include/cygwin/version.h
index f3321020f7..00eedeb27a 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 5900e6315d..a22528ab48 100644
--- a/winsup/cygwin/lib/_cygwin_crt0_common.cc
+++ b/winsup/cygwin/lib/_cygwin_crt0_common.cc
@@ -124,6 +124,8 @@ _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 =
+       CYGWIN_VERSION_CHECK_FOR_CXX17_OVERLOADS (newu);

   /* 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.  */
@@ -176,12 +178,13 @@ _cygwin_crt0_common (MainFunc f, per_process *u)
   /* Likewise for the C++ memory operators, if any, but not if we
      were dlopen()'d, as we might get dlclose()'d and that would
      leave stale function pointers behind.    */
-  if (newu && newu->cxx_malloc && !__dynamically_loaded)
+  if (!__dynamically_loaded)
     {
       /* Inherit what we don't override.  */
 #define CONDITIONALLY_OVERRIDE(MEMBER) \
-      if (!__cygwin_cxx_malloc.MEMBER) \
-       __cygwin_cxx_malloc.MEMBER = newu->cxx_malloc->MEMBER;
+      if (__cygwin_cxx_malloc.MEMBER) \
+       newu->cxx_malloc->MEMBER = __cygwin_cxx_malloc.MEMBER;
+
       CONDITIONALLY_OVERRIDE(oper_new);
       CONDITIONALLY_OVERRIDE(oper_new__);
       CONDITIONALLY_OVERRIDE(oper_delete);
@@ -190,20 +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);
-      /* Now update the resulting set into the global redirectors.  */
-      *newu->cxx_malloc = __cygwin_cxx_malloc;
+      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);
+       }
     }

   /* Setup the module handle so fork can get the path name.  */
-- 
2.50.1.windows.1

Reply via email to