On Saturday 09 November 2024 16:27:09 Pali Rohár wrote: > 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.
Hello, now I have figured out that this issue is quite more complicated. msvcrt.dll version from the original Visual C++ and also system version of msvcrt.dll before Windows XP has really the "void" as return value. In these versions of msvcrt.dll library, those two functions either success or terminate process (e.g. because of memory allocation failure). But starting from Windows XP, the msvcrt.dll system library for these two functions __getmainargs() and __wgetmainargs() returns int value which indicates either success or memory allocation failure. And it is up to the caller to terminate process. Currently in mingw-w64 crtexe.c ignored failure from these two functions, which matches the Visual C++ ABI, where msvcrt.dll itself is responsible for handling failures and terminates process on error. I think that we should not ignore memory allocation failures. I can try to prepare some compatible wrapper for this function which would handle both ABIs to preserve compatibility with both versions of msvcrt.dll. Visual C++ ABI of __get(w)mainargs() does not touch argc/argv/envp pointer arguments on failure. So we can store there some sentinel value and check that __get(w)mainargs() overwrite it, which would indicate success of the function. What do you think about it? > 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. > ... _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public