Hello, now, when looking at this issue, I have figured out that in
mingw-w64 is declaration of __getmainargs() and __wgetmainargs()
functions incompatible with msvcrt.dll library.

In header file mingw-w64-crt/include/internal.h is:

_CRTIMP int __cdecl __getmainargs(int * _Argc, char *** _Argv, char ***_Env, 
int _DoWildCard, _startupinfo *_StartInfo);
_CRTIMP int __cdecl __wgetmainargs(int * _Argc, wchar_t ***_Argv, wchar_t 
***_Env, int _DoWildCard, _startupinfo *_StartInfo);

But version in msvcrt.dll has "void" as a return value.

Return value "int" is available since VC70 version msvcr70.dll, so
header files are compatible with msvcr70.dll (and new), but not with
older versions msvcrt.dll and msvcrt40.dll (crtdll.dll, msvcrt10.dll,
msvcrt20.dll has custom wrapper for compatibility).

Return value of __wgetmainargs() function is stored into the argret
variable, but it is not used. So for now it is safe. But if runtime
would be changed to use the return value then for msvcrt.dll build,
in this variable would be stored some garbage from temp register.

So basically for msvcrt.dll builds, __getmainargs() and __wgetmainargs()
do not return anything. For new versions they return negative value on
memory allocation errors, and zero on success.

I think that we should not ignore errors from __getmainargs() and
__wgetmainargs() calls (when building with new msvcr*.dll libs), but for
msvcrt.dll compatibility (which is os system library) it cannot be done
globally.

What about simple wrapper for msvcrt.dll builds, like we already have
for crtdll.dll/msvcrt[12].dll builds? Such thing can be used also for
fixing that security issue.

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index f3c65cf28d3b..3b2129a786fa 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -160,6 +160,8 @@ src_libws2_32=libsrc/ws2_32.c \
 
 # Files included in all libmsvcr*.a
 src_msvcrt_common=\
+  misc/msvcrt__getmainargs.c \
+  misc/msvcrt__wgetmainargs.c \
   misc/_onexit.c \
   misc/mbsinit.c \
   misc/onexit_table.c \
@@ -800,6 +802,8 @@ src_pre_msvcrt60=\
   stdio/mingw_dummy__lock.c
 
 src_pre_msvcr70=\
+  misc/msvcrt__getmainargs.c \
+  misc/msvcrt__wgetmainargs.c \
   misc/___mb_cur_max_func.c \
   misc/__pctype_func.c \
   misc/__pwctype_func.c \
diff --git a/mingw-w64-crt/lib-common/msvcrt.def.in 
b/mingw-w64-crt/lib-common/msvcrt.def.in
index 07274a31092f..dd6d0da1d7fd 100644
--- a/mingw-w64-crt/lib-common/msvcrt.def.in
+++ b/mingw-w64-crt/lib-common/msvcrt.def.in
@@ -459,7 +459,7 @@ __crtLCMapStringA
 __dllonexit
 __doserrno
 __fpecode
-__getmainargs
+__msvcrt_getmainargs == __getmainargs ; msvcrt.dll's __getmainargs is 
incompatible with mingw-w64's __getmainargs, real __getmainargs provided by emu
 F_X86_ANY(__initenv DATA) ; arm32 and arm64 __initenv provided by emu
 __isascii
 __iscsym
@@ -507,7 +507,7 @@ __toascii
 __unDName
 F_X86_ANY(__unguarded_readlc_active DATA)
 __wargv DATA
-__wgetmainargs
+__msvcrt_wgetmainargs == __wgetmainargs ; msvcrt.dll's __wgetmainargs is 
incompatible with mingw-w64's __wgetmainargs, real __wgetmainargs provided by 
emu
 F_X86_ANY(__winitenv DATA) ; arm32 and arm64 __winitenv provided by emu
 F_I386(_abnormal_termination)
 _access
diff --git a/mingw-w64-crt/lib32/msvcr40d.def.in 
b/mingw-w64-crt/lib32/msvcr40d.def.in
index b9d3f93f984d..a44fc738b6e9 100644
--- a/mingw-w64-crt/lib32/msvcr40d.def.in
+++ b/mingw-w64-crt/lib32/msvcr40d.def.in
@@ -1022,7 +1022,7 @@ __STRINGTOLD
 __dllonexit
 __doserrno
 __fpecode
-__getmainargs
+__msvcrt_getmainargs == __getmainargs ; msvcr40d.dll's __getmainargs is 
incompatible with mingw-w64's __getmainargs, real __getmainargs provided by emu
 __isascii
 __iscsym
 __iscsymf
@@ -1063,7 +1063,7 @@ __threadhandle
 __threadid
 __toascii
 __unDName
-__wgetmainargs
+__msvcrt_wgetmainargs == __wgetmainargs ; msvcr40d.dll's __wgetmainargs is 
incompatible with mingw-w64's __wgetmainargs, real __wgetmainargs provided by 
emu
 _abnormal_termination
 _access
 _adj_fdiv_m16i ; msvc symbol is without decoration but callee pop stack (like 
stdcall @4)
diff --git a/mingw-w64-crt/lib32/msvcrt40.def.in 
b/mingw-w64-crt/lib32/msvcrt40.def.in
index 5fae1d0851a0..ce463b298307 100644
--- a/mingw-w64-crt/lib32/msvcrt40.def.in
+++ b/mingw-w64-crt/lib32/msvcrt40.def.in
@@ -999,7 +999,7 @@ __STRINGTOLD
 __dllonexit
 __doserrno
 __fpecode
-__getmainargs
+__msvcrt_getmainargs == __getmainargs ; msvcrt40.dll's __getmainargs is 
incompatible with mingw-w64's __getmainargs, real __getmainargs provided by emu
 __isascii
 __iscsym
 __iscsymf
@@ -1037,7 +1037,7 @@ __threadhandle
 __threadid
 __toascii
 __unDName
-__wgetmainargs
+__msvcrt_wgetmainargs == __wgetmainargs ; msvcrt40.dll's __wgetmainargs is 
incompatible with mingw-w64's __wgetmainargs, real __wgetmainargs provided by 
emu
 _abnormal_termination
 _access
 _adj_fdiv_m16i ; msvc symbol is without decoration but callee pop stack (like 
stdcall @4)
diff --git a/mingw-w64-crt/lib32/msvcrtd.def.in 
b/mingw-w64-crt/lib32/msvcrtd.def.in
index df2fbfd3120b..5da857a8e9dd 100644
--- a/mingw-w64-crt/lib32/msvcrtd.def.in
+++ b/mingw-w64-crt/lib32/msvcrtd.def.in
@@ -165,7 +165,7 @@ __crtLCMapStringA
 __dllonexit
 __doserrno
 __fpecode
-__getmainargs
+__msvcrt_getmainargs == __getmainargs ; msvcrtd.dll's __getmainargs is 
incompatible with mingw-w64's __getmainargs, real __getmainargs provided by emu
 __initenv DATA
 __isascii
 __iscsym
@@ -216,7 +216,7 @@ __toascii
 __unDName
 __unguarded_readlc_active DATA
 __wargv DATA
-__wgetmainargs
+__msvcrt_wgetmainargs == __wgetmainargs ; msvcrtd.dll's __wgetmainargs is 
incompatible with mingw-w64's __wgetmainargs, real __wgetmainargs provided by 
emu
 __winitenv DATA
 _abnormal_termination
 _access
diff --git a/mingw-w64-crt/misc/msvcrt__getmainargs.c 
b/mingw-w64-crt/misc/msvcrt__getmainargs.c
new file mode 100644
index 000000000000..f2ba8bf0b284
--- /dev/null
+++ b/mingw-w64-crt/misc/msvcrt__getmainargs.c
@@ -0,0 +1,15 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include <internal.h>
+
+/* Define __getmainargs() function via msvcrt40.dll / msvcrt.dll 
__getmainargs() function */
+_CRTIMP void __cdecl __msvcrt_getmainargs(int *argc, char ***argv, char 
***envp, int expand_wildcards, _startupinfo *startup_info);
+int __cdecl __getmainargs(int *argc, char ***argv, char ***envp, int 
expand_wildcards, _startupinfo *startup_info)
+{
+  __msvcrt_getmainargs(argc, argv, envp, expand_wildcards, startup_info);
+  return 0;
+}
diff --git a/mingw-w64-crt/misc/msvcrt__wgetmainargs.c 
b/mingw-w64-crt/misc/msvcrt__wgetmainargs.c
new file mode 100644
index 000000000000..0e46d47f611d
--- /dev/null
+++ b/mingw-w64-crt/misc/msvcrt__wgetmainargs.c
@@ -0,0 +1,15 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include <internal.h>
+
+/* Define __wgetmainargs() function via msvcrt40.dll / msvcrt.dll 
__wgetmainargs() function */
+_CRTIMP void __cdecl __msvcrt_wgetmainargs(int *argc, wchar_t ***argv, wchar_t 
***envp, int expand_wildcards, _startupinfo *startup_info);
+int __cdecl __wgetmainargs(int *argc, wchar_t ***argv, wchar_t ***envp, int 
expand_wildcards, _startupinfo *startup_info)
+{
+  __msvcrt_wgetmainargs(argc, argv, envp, expand_wildcards, startup_info);
+  return 0;
+}


_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to