While the compiler drivers do add -lssp automatically when linking with -fstack-protector-strong, this also allows relying entirely on libmingwex. This implementation should be functionally equivalent to GCC's libssp for a mingw build configuration.
This allows toolchains that don't otherwise use GCC's runtime libraries (such as LLVM based ones) to skip building libssp from GCC (and replacing it with empty/dummy libssp.a and libssp_nonshared.a). Signed-off-by: Martin Storsjö <[email protected]> --- v2: Same updates to the __stack_chk_fail function as for __chk_fail in the previous patch. v3: Switch implementation to use rand_s() instead of Crypt* functions. This single rand_s() call should work everywhere we need it to; from XP to newer versions, and in all versions of WinStore/UWP. (Internally, the function allegedly uses RtlGenRandom.) --- mingw-w64-crt/Makefile.am | 4 +-- mingw-w64-crt/ssp/stack_chk_fail.c | 23 +++++++++++++++++ mingw-w64-crt/ssp/stack_chk_guard.c | 40 +++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 mingw-w64-crt/ssp/stack_chk_fail.c create mode 100644 mingw-w64-crt/ssp/stack_chk_guard.c diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am index 007eb5ffb..053eab3cf 100644 --- a/mingw-w64-crt/Makefile.am +++ b/mingw-w64-crt/Makefile.am @@ -565,8 +565,8 @@ src_libmingwex=\ misc/wmemset.c misc/ftw.c misc/ftw64.c misc/mingw-access.c \ \ ssp/chk_fail.c ssp/memcpy_chk.c ssp/memmove_chk.c ssp/mempcpy_chk.c \ - ssp/memset_chk.c ssp/strcat_chk.c ssp/strcpy_chk.c ssp/strncat_chk.c \ - ssp/strncpy_chk.c \ + ssp/memset_chk.c ssp/stack_chk_fail.c ssp/stack_chk_guard.c ssp/strcat_chk.c \ + ssp/strcpy_chk.c ssp/strncat_chk.c ssp/strncpy_chk.c \ \ stdio/mingw_pformat.h \ stdio/scanf2-argcount-char.c stdio/scanf2-argcount-wchar.c \ diff --git a/mingw-w64-crt/ssp/stack_chk_fail.c b/mingw-w64-crt/ssp/stack_chk_fail.c new file mode 100644 index 000000000..5619dd888 --- /dev/null +++ b/mingw-w64-crt/ssp/stack_chk_fail.c @@ -0,0 +1,23 @@ +/** + * 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 <stdio.h> +#include <io.h> +#include <stdlib.h> +#include <windows.h> + +void __cdecl __attribute__((__noreturn__)) __stack_chk_fail(void); + +void __cdecl __attribute__((__noreturn__)) __stack_chk_fail(void) { + static const char msg[] = "*** stack smashing detected ***: terminated\n"; + write(STDERR_FILENO, msg, strlen(msg)); + if (IsProcessorFeaturePresent(PF_FASTFAIL_AVAILABLE)) { + __fastfail(FAST_FAIL_STACK_COOKIE_CHECK_FAILURE); + } else { + TerminateProcess(GetCurrentProcess(), STATUS_STACK_BUFFER_OVERRUN); + __builtin_unreachable(); + } +} diff --git a/mingw-w64-crt/ssp/stack_chk_guard.c b/mingw-w64-crt/ssp/stack_chk_guard.c new file mode 100644 index 000000000..3ff22e020 --- /dev/null +++ b/mingw-w64-crt/ssp/stack_chk_guard.c @@ -0,0 +1,40 @@ +/** + * 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. + */ + +#define _CRT_RAND_S +#include <stdlib.h> +#include <stdint.h> + +void *__stack_chk_guard; + +static void __cdecl __attribute__((__constructor__)) init(void) +{ + unsigned int ui; + if (__stack_chk_guard != 0) + return; + + // Call rand_s from the CRT; this uses a high quality random source + // RtlGenRandom internally. This function is available since XP, and is + // callable in WinStore mode too (since it's from the CRT). + // In the case of msvcrt.dll, our import library provides a small wrapper + // which tries to load the function dynamically, and falls back on + // using RtlRandomGen if not available. + if (rand_s(&ui) == 0) { + __stack_chk_guard = (void*)(intptr_t)ui; +#if __SIZEOF_POINTER__ > 4 + rand_s(&ui); + __stack_chk_guard = (void*)(((intptr_t)__stack_chk_guard) << 32 | ui); +#endif + return; + } + + // If rand_s failed (it shouldn't), hardcode a nonzero default stack guard. +#if __SIZEOF_POINTER__ > 4 + __stack_chk_guard = (void*)0xdeadbeefdeadbeefULL; +#else + __stack_chk_guard = (void*)0xdeadbeef; +#endif +} -- 2.25.1 _______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
