On Sat, 11 Jan 2025, Martin Storsjö wrote:

On Fri, 10 Jan 2025, Pali Rohár wrote:

On Friday 10 January 2025 12:32:41 Martin Storsjö wrote:
On Mon, 6 Jan 2025, Pali Rohár wrote:

All 32-bit Windows NT systems contains system OS library msvcrt40.dll which should be compatible with the original Visual C++ 4.0/4.1 msvcrt40.dll library.

The Windows NT implementation of msvcrt40.dll is very simple, it just
redirects function calls via symbol forwarding to msvcrt.dll library.

Since Windows XP, the msvcrt.dll changed ABI of __getmainargs() and
__wgetmainargs() functions, and so it is required also for msvcrt40.dll builds to include ABI fix code which is already used for msvcrt.dll builds. Otherwise applications compiled with new mingw-w64 checks introduced since commit 3e043834e993 ("crt: Check for return value from __(w)getmainargs() calls") would crash on Windows XP+ systems if they would use the system
msvcrt40.dll library.

I don't understand why they would crash?

I have not explained it correctly. As msvcrt40.dll __getmainargs()
redirects to msvcrt.dll __getmainargs(), it means that msvcrt40 builds
have exactly same issues as msvcrt builds. For msvcrt builds we provide
that wrapper for fixing fails.

If they are compiled with misc/msvcrt40__getmainargs.c, they end up calling msvcrt40.dll's __getmainargs(), ignoring any return value from it, as it is
expected to have a void return type.

If that code runs on a newer msvcrt40.dll (which redirects to msvcrt.dll, with the new ABI), I don't see how things would crash? On success, it should work just fine. _If_ there's a failure in it, we would miss it though - as
misc/msvcrt40__getmainargs.c expects that the function terminates the
process on error, while it would just return an error code and expect the
caller to handle it.

The issue is on the failure code path. misc/msvcrt40__getmainargs.c is
ignoring return value from msvcrt40.dll's __getmainargs() and is
returning 0 even when __getmainargs() failed. WinXP+ msvcrt40.dll does
not terminate process on error and expects caller to handle failure.

Crash can happen because crt startup code thinks that argv was properly
filled when it returns 0, but on failure it is not (and 0 is still
returned). Application main() code then dereference argv and NULL
pointer dereference happens.

Right, ok, so it fixes catching the errors - that explanation I'm ok with.

To explain why I found the initial explanation so misleading: Before 3e043834e993258833d62ae8d0b11d0e4958770f, "crt: Check for return value from __(w)getmainargs() calls", we always had the same situation, we would ignore errors from __getmainargs - and thus would crash afterwards if __getmainargs failed and we used an uninitialized argv. This has been the situation since essentially forever, and we haven't had any reports about this being an issue anywhere in the wild. Catching errors if there are any obviously is good to do anyway. But we can't say "mingw-w64 versions before 3e043834e99 will crash", that's just a very misleading explanation of the issue.

Pushed these two changes now; I updated the commit message of the first one, removing the misleading sentences.

// Martin

_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to