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

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.

Reviewed-on: https://github.com/dlang/druntime/pull/3293

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.
This commit is contained in:
Iain Buclaw 2020-11-27 13:15:44 +01:00
parent 6b2f370fa9
commit 5dbab7b3f4
10 changed files with 43 additions and 9 deletions

View File

@ -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@

16
libphobos/configure vendored
View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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@

View File

@ -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)

View File

@ -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:

View File

@ -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@;

View File

@ -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@

View File

@ -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@