Hi,
On 15/9/2022 3:29, Martin Storsjö wrote:
> On Thu, 15 Sep 2022, Alvin Wong wrote:
>
>> Hi,
>>
>> On 14/9/2022 15:33, Martin Storsjö wrote:
>>> +void __cdecl __attribute__((__noreturn__)) __stack_chk_fail(void) {
>>> + char msg[] = "*** stack smashing detected ***: terminated\n";
>>> + write(STDERR_FILENO, msg, strlen(msg));
>>> + abort();
>>> +}
>>
>> I have a feeling that calling `abort()` may not be the best thing to do
>> here. From what I recall, `abort` may call `_exit(3)` in some cases (or
>> perhaps some CRT combinations) and that causes DLLs to be unloaded and
>> global destructors to be run. In case of a stack smashing event, the process
>> memory has been corrupted so allowing arbitrary destructors to run could be
>> a security risk.
>
> Right, that's clearly not ideal. I tested this - on UCRT, abort() doesn't
> seem to run DLL destructors, while on msvcrt.dll, it does. So we should
> indeed pick something else.
>
> GCC's libssp calls a createive combo of __builtin_trap(), followed by an
> explicit invalid write out of bounds, followed by _exit():
> https://github.com/gcc-mirror/gcc/blob/releases/gcc-12.2.0/libssp/ssp.c#L158-L178
IIRC __builtin_trap uses ud2 which does trigger the unhandled exception
handler, which can also run arbitrary user code. Same goes for access
violation. Not ideal either.
> As we're free to use any Windows specific APIs here, I considered using
> TerminateProcess() - but I preferred to avoid that as it's not available for
> older Windows Store apps (targeting Windows 8.x iirc). (We do have a fallback
> implementation of it for such older Windows Store builds in the
> winstorecompat library, but there it only boils down to calling _exit().)
>
> But since probably very few do care about those older Windows Store targets
> at this point, maybe that's not that much of an issue any longer?
>
>> I think MSVC raises fail fast exceptions for all kinds of security check
>> failures including /GS buffer security checks. Perhaps the same will be more
>> appropriate here?
>
> Hmm, I'm not very familiar with those APIs, can you give an example of what
> that would look like?
Sorry, I got confused -- it's fast fail request instead of fail fast exception.
There is a compiler intrinsic `__fastfail` [1] designed for this. I believe for
/GS failure it is called with the code `FAST_FAIL_STACK_COOKIE_CHECK_FAILURE`.
This intrinsic doesn't seem to be available for mingw-w64 yet but it should be
simple to implement according to the docs.
(There is a separate API called `RaiseFailFastException` which does different
things, though it can also bypass unhandled exception handlers.)
But it turns out the __fastfail mechanism is only available starting from
Windows 8, so it needs a separate code path for Windows 7 or earlier. I had to
check what MSVC does. The handler is in `vcruntime/gs_report.c`: It first
checks for __fastfail support using
`IsProcessorFeaturePresent(PF_FASTFAIL_AVAILABLE)` and use that if true,
otherwise it does a long fallback routine (at the same time trying to avoid
overwriting a chunk of the original stack) by manually building a fake
`EXCEPTION_POINTERS` struct, then calls `SetUnhandledExceptionFilter(NULL)` and
`UnhandledExceptionFilter(exception_pointers)` to report the exception
(triggering the default application error message box or the debugger if
attached), then finally calls `TerminateProcess` as an end. This all seems
overcomplicated but appears to be needed to break in the debugger or to allow a
debugger to be attached while bypassing user exception handlers.
I am not sure if it is worth the trouble to reimplement the same fallback
rather than to just call TerminateProcess (it's only needed <= Win7 so
shouldn't be a problem for the Windows Store target). RaiseFailFastException
could be an alternative which does break the debugger, but unfortunately it is
only available starting from Win7. (Is XP still a supported target?) If you do
use TerminateProces, the best exit code should be
`STATUS_SECURITY_CHECK_FAILURE`.
[1]: https://docs.microsoft.com/en-us/cpp/intrinsics/fastfail
Best Regards,
Alvin Wong
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public