[newlib-cygwin] Cygwin: add api version check to c++ malloc struct override.
Jeremy Drake
jeremyd2019@sourceware.org
Mon Aug 4 16:59:22 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=276eb28273f3dae420ff27bdb3baaca6964b5ed7
commit 276eb28273f3dae420ff27bdb3baaca6964b5ed7
Author: Jeremy Drake <cygwin@jdrake.com>
Date: Fri Aug 1 11:03:00 2025 -0700
Cygwin: add api version check to c++ malloc struct override.
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 <corinna@vinschen.de>
Signed-off-by: Jeremy Drake <cygwin@jdrake.com>
Diff:
---
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 d8e058f19..86b0c2718 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 f3321020f..00eedeb27 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 5900e6315..a22528ab4 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. */
More information about the Cygwin-cvs
mailing list