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

Reply via email to