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

Reply via email to