diff mbox series

[committed] libphobos: Fix segfault at run-time when using custom Fibers (PR 98025)

Message ID 20201127203026.47440-1-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] libphobos: Fix segfault at run-time when using custom Fibers (PR 98025) | expand

Commit Message

Iain Buclaw Nov. 27, 2020, 8:30 p.m. UTC
Hi,

When libphobos is configured with --enable-cet, this adds extra fields
to the Fiber class to support the ucontext_t fallback implementation.
These fields get omitted when compiling user code unless they also used
`-fversion=CET' to build their project, which resulted in data being
overwritten from within swapcontext().

On reviewing the ucontext_t definitions, it was found that the shadow
stack fields were missing, and the struct size didn't match up on X32.
This has been fixed in upstream druntime and merged down here.

Bootstrapped and regression tested on x86_64-linux-gnu with -mx32/-m32,
committed to mainline.

Regards
Iain.

---
libphobos/ChangeLog:

	PR d/98025
	* Makefile.in: Regenerate.
	* configure: Regenerate.
	* configure.ac (DCFG_ENABLE_CET): Substitute.
	* libdruntime/MERGE: Merge upstream druntime 0fe7974c.
	* libdruntime/Makefile.in: Regenerate.
	* libdruntime/core/thread.d: Import gcc.config.
	(class Fiber): Add ucontext_t fields when GNU_Enable_CET is true.
	* libdruntime/gcc/config.d.in (GNU_Enable_CET): Define.
	* src/Makefile.in: Regenerate.
	* testsuite/Makefile.in: Regenerate.
---
 libphobos/Makefile.in                           |  1 +
 libphobos/configure                             | 16 +++++++++++++---
 libphobos/configure.ac                          | 11 ++++++++---
 libphobos/libdruntime/MERGE                     |  2 +-
 libphobos/libdruntime/Makefile.in               |  1 +
 libphobos/libdruntime/core/sys/posix/ucontext.d |  6 ++++--
 libphobos/libdruntime/core/thread.d             | 10 ++++++++++
 libphobos/libdruntime/gcc/config.d.in           |  3 +++
 libphobos/src/Makefile.in                       |  1 +
 libphobos/testsuite/Makefile.in                 |  1 +
 10 files changed, 43 insertions(+), 9 deletions(-)
diff mbox series

Patch

diff --git a/libphobos/Makefile.in b/libphobos/Makefile.in
index f692b2f719e..a1395929819 100644
--- a/libphobos/Makefile.in
+++ b/libphobos/Makefile.in
@@ -217,6 +217,7 @@  CPPFLAGS = @CPPFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DCFG_ARM_EABI_UNWINDER = @DCFG_ARM_EABI_UNWINDER@
 DCFG_DLPI_TLS_MODID = @DCFG_DLPI_TLS_MODID@
+DCFG_ENABLE_CET = @DCFG_ENABLE_CET@
 DCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@
 DCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@
 DCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@
diff --git a/libphobos/configure b/libphobos/configure
index 6d8461febf9..77a3125cbd6 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -722,6 +722,7 @@  LIBTOOL
 CFLAGS_FOR_BUILD
 CC_FOR_BUILD
 AR
+DCFG_ENABLE_CET
 CET_DFLAGS
 CET_FLAGS
 RANLIB
@@ -5652,11 +5653,20 @@  fi
 
 
 # To ensure that runtime code for CET is compiled in, add in D version flags.
-if test "$enable_cet" = yes; then
+if test x$enable_cet = xyes; then :
+
   CET_DFLAGS="$CET_FLAGS -fversion=CET"
+  DCFG_ENABLE_CET=true
+
+else
+
+  CET_DFLAGS=
+  DCFG_ENABLE_CET=false
 
 fi
 
+
+
 # This should be inherited in the recursive make, but ensure it is defined.
 test "$AR" || AR=ar
 
@@ -11744,7 +11754,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11747 "configure"
+#line 11757 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11850,7 +11860,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11853 "configure"
+#line 11863 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
diff --git a/libphobos/configure.ac b/libphobos/configure.ac
index 60aee3ffe8b..2d51e465a15 100644
--- a/libphobos/configure.ac
+++ b/libphobos/configure.ac
@@ -69,10 +69,15 @@  AC_PROG_MAKE_SET
 GCC_CET_FLAGS(CET_FLAGS)
 AC_SUBST(CET_FLAGS)
 # To ensure that runtime code for CET is compiled in, add in D version flags.
-if test "$enable_cet" = yes; then
+AS_IF([test x$enable_cet = xyes], [
   CET_DFLAGS="$CET_FLAGS -fversion=CET"
-  AC_SUBST(CET_DFLAGS)
-fi
+  DCFG_ENABLE_CET=true
+], [
+  CET_DFLAGS=
+  DCFG_ENABLE_CET=false
+])
+AC_SUBST(CET_DFLAGS)
+AC_SUBST(DCFG_ENABLE_CET)
 
 # This should be inherited in the recursive make, but ensure it is defined.
 test "$AR" || AR=ar
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 6b65a44e6d2..7162844b9b6 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@ 
-d37ef985a97eb446371ab4b2315a52b87233fbf3
+0fe7974cf53b75db59461de2a3d6e53ce933d297
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/druntime repository.
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 0b895142a13..99ee8b92afa 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -577,6 +577,7 @@  CPPFLAGS = @CPPFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DCFG_ARM_EABI_UNWINDER = @DCFG_ARM_EABI_UNWINDER@
 DCFG_DLPI_TLS_MODID = @DCFG_DLPI_TLS_MODID@
+DCFG_ENABLE_CET = @DCFG_ENABLE_CET@
 DCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@
 DCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@
 DCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@
diff --git a/libphobos/libdruntime/core/sys/posix/ucontext.d b/libphobos/libdruntime/core/sys/posix/ucontext.d
index 49a7c3e389a..2e518aefa84 100644
--- a/libphobos/libdruntime/core/sys/posix/ucontext.d
+++ b/libphobos/libdruntime/core/sys/posix/ucontext.d
@@ -114,7 +114,7 @@  version (CRuntime_Glibc)
 
             enum NGREG = 23;
 
-            alias c_long            greg_t;
+            alias long              greg_t;
             alias greg_t[NGREG]     gregset_t;
             alias _libc_fpstate*    fpregset_t;
         }
@@ -123,7 +123,7 @@  version (CRuntime_Glibc)
         {
             gregset_t   gregs;
             fpregset_t  fpregs;
-            c_ulong[8]  __reserved1;
+            ulong[8]    __reserved1;
         }
 
         struct ucontext_t
@@ -134,6 +134,7 @@  version (CRuntime_Glibc)
             mcontext_t      uc_mcontext;
             sigset_t        uc_sigmask;
             _libc_fpstate   __fpregs_mem;
+            ulong[4]        __ssp;
         }
     }
     else version (X86)
@@ -205,6 +206,7 @@  version (CRuntime_Glibc)
             mcontext_t      uc_mcontext;
             sigset_t        uc_sigmask;
             _libc_fpstate   __fpregs_mem;
+            c_ulong[4]      __ssp;
         }
     }
     else version (HPPA)
diff --git a/libphobos/libdruntime/core/thread.d b/libphobos/libdruntime/core/thread.d
index eaf088d53c1..7506a8b3ee3 100644
--- a/libphobos/libdruntime/core/thread.d
+++ b/libphobos/libdruntime/core/thread.d
@@ -52,6 +52,7 @@  version (Solaris)
 version (GNU)
 {
     import gcc.builtins;
+    import gcc.config;
     version (GNU_StackGrowsDown)
         version = StackGrowsDown;
 }
@@ -5123,6 +5124,15 @@  private:
         ucontext_t              m_utxt  = void;
         ucontext_t*             m_ucur  = null;
     }
+    else static if (GNU_Enable_CET)
+    {
+        // When libphobos was built with --enable-cet, these fields need to
+        // always be present in the Fiber class layout.
+        import core.sys.posix.ucontext;
+        static ucontext_t       sm_utxt = void;
+        ucontext_t              m_utxt  = void;
+        ucontext_t*             m_ucur  = null;
+    }
 
 
 private:
diff --git a/libphobos/libdruntime/gcc/config.d.in b/libphobos/libdruntime/gcc/config.d.in
index 6301aaff069..9ac7d055271 100644
--- a/libphobos/libdruntime/gcc/config.d.in
+++ b/libphobos/libdruntime/gcc/config.d.in
@@ -49,3 +49,6 @@  enum GNU_Have_LibAtomic = @DCFG_HAVE_LIBATOMIC@;
 
 // Do we have qsort_r function
 enum Have_Qsort_R = @DCFG_HAVE_QSORT_R@;
+
+// Whether libphobos been configured with --enable-cet.
+enum GNU_Enable_CET = @DCFG_ENABLE_CET@;
diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in
index 4a0612a613b..2e721783d06 100644
--- a/libphobos/src/Makefile.in
+++ b/libphobos/src/Makefile.in
@@ -333,6 +333,7 @@  CPPFLAGS = @CPPFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DCFG_ARM_EABI_UNWINDER = @DCFG_ARM_EABI_UNWINDER@
 DCFG_DLPI_TLS_MODID = @DCFG_DLPI_TLS_MODID@
+DCFG_ENABLE_CET = @DCFG_ENABLE_CET@
 DCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@
 DCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@
 DCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@
diff --git a/libphobos/testsuite/Makefile.in b/libphobos/testsuite/Makefile.in
index 2f6911d4d47..c38a4688258 100644
--- a/libphobos/testsuite/Makefile.in
+++ b/libphobos/testsuite/Makefile.in
@@ -161,6 +161,7 @@  CPPFLAGS = @CPPFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DCFG_ARM_EABI_UNWINDER = @DCFG_ARM_EABI_UNWINDER@
 DCFG_DLPI_TLS_MODID = @DCFG_DLPI_TLS_MODID@
+DCFG_ENABLE_CET = @DCFG_ENABLE_CET@
 DCFG_HAVE_64BIT_ATOMICS = @DCFG_HAVE_64BIT_ATOMICS@
 DCFG_HAVE_ATOMIC_BUILTINS = @DCFG_HAVE_ATOMIC_BUILTINS@
 DCFG_HAVE_LIBATOMIC = @DCFG_HAVE_LIBATOMIC@