This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

V3 [PATCH 03/24] x86: Support IBT and SHSTK in Intel CET [BZ #21598]


On 07/10/2018 06:09 PM, H.J. Lu wrote:
> On Sat, Jul 7, 2018 at 1:01 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Fri, Jul 06, 2018 at 03:47:27PM -0400, Carlos O'Donell wrote:
>>> On 06/13/2018 11:31 AM, H.J. Lu wrote:
>>>> Intel Control-flow Enforcement Technology (CET) instructions:
>>> Reviewed.
>>>
>>> Looking forward to v2.
>>>
> Here is V3.  The difference from V2 is that get_cet_status became:
> 
> static inline int __attribute__ ((always_inline))
> get_cet_status (void)
> {
>   return 0;
> }
> 

Thank you for the update.

With the following changes:
- Add suggested comment to sysdeps/generic/dl-prop.h.
- Make dl_cet_mark_legacy_region return -1 on error.
- Fix typo s/fail/failed/g

This version is OK.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

> -- H.J.
> 
> 
> 0003-x86-Support-IBT-and-SHSTK-in-Intel-CET-BZ-21598.patch
> 
> 
> From b100bb5197020c403bf53f26b94324d04e4a0d45 Mon Sep 17 00:00:00 2001
> From: "H.J. Lu" <hjl.tools@gmail.com>
> Date: Thu, 22 Jun 2017 04:15:39 -0700
> Subject: [PATCH 03/24] x86: Support IBT and SHSTK in Intel CET [BZ #21598]
> 
> Intel Control-flow Enforcement Technology (CET) instructions:
> 
> https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-en
> forcement-technology-preview.pdf
> 
> includes Indirect Branch Tracking (IBT) and Shadow Stack (SHSTK).
> 
> GNU_PROPERTY_X86_FEATURE_1_IBT is added to GNU program property to
> indicate that all executable sections are compatible with IBT when
> ENDBR instruction starts each valid target where an indirect branch
> instruction can land.  Linker sets GNU_PROPERTY_X86_FEATURE_1_IBT on
> output only if it is set on all relocatable inputs.
> 
> On an IBT capable processor, the following steps should be taken:
> 
> 1. When loading an executable without an interpreter, enable IBT and
> lock IBT if GNU_PROPERTY_X86_FEATURE_1_IBT is set on the executable.
> 2. When loading an executable with an interpreter, enable IBT if
> GNU_PROPERTY_X86_FEATURE_1_IBT is set on the interpreter.
>   a. If GNU_PROPERTY_X86_FEATURE_1_IBT isn't set on the executable,
>      disable IBT.
>   b. Lock IBT.
> 3. If IBT is enabled, when loading a shared object without
> GNU_PROPERTY_X86_FEATURE_1_IBT:
>   a. If legacy interwork is allowed, then mark all pages in executable
>      PT_LOAD segments in legacy code page bitmap.  Failure of legacy code
>      page bitmap allocation causes an error.
>   b. If legacy interwork isn't allowed, it causes an error.

OK.

> GNU_PROPERTY_X86_FEATURE_1_SHSTK is added to GNU program property to
> indicate that all executable sections are compatible with SHSTK where
> return address popped from shadow stack always matches return address
> popped from normal stack.  Linker sets GNU_PROPERTY_X86_FEATURE_1_SHSTK
> on output only if it is set on all relocatable inputs.
> 
> On a SHSTK capable processor, the following steps should be taken:
> 
> 1. When loading an executable without an interpreter, enable SHSTK if
> GNU_PROPERTY_X86_FEATURE_1_SHSTK is set on the executable.
> 2. When loading an executable with an interpreter, enable SHSTK if
> GNU_PROPERTY_X86_FEATURE_1_SHSTK is set on interpreter.
>   a. If GNU_PROPERTY_X86_FEATURE_1_SHSTK isn't set on the executable
>      or any shared objects loaded via the DT_NEEDED tag, disable SHSTK.
>   b. Otherwise lock SHSTK.
> 3. After SHSTK is enabled, it is an error to load a shared object
> without GNU_PROPERTY_X86_FEATURE_1_SHSTK.

OK.

> To enable CET support in glibc, --enable-cet is required to configure
> glibc.  When CET is enabled, both compiler and assembler must support
> CET.  Otherwise, it is a configure-time error.

OK.

> To support CET run-time control,
> 
> 1. _dl_x86_feature_1 is added to the writable ld.so namespace to indicate
> if IBT or SHSTK are enabled at run-time.  It should be initialized by
> init_cpu_features.
> 2. For dynamic executables:
>    a. A l_cet field is added to struct link_map to indicate if IBT or
>       SHSTK is enabled in an ELF module.  _dl_process_pt_note or
>       _rtld_process_pt_note is called to process PT_NOTE segment for
>       GNU program property and set l_cet.
>    b. _dl_open_check is added to check IBT and SHSTK compatibilty when
>       dlopening a shared object.
> 3. Replace i386 _dl_runtime_resolve and _dl_runtime_profile with
> _dl_runtime_resolve_shstk and _dl_runtime_profile_shstk, respectively if
> SHSTK is enabled.

OK.

> CET run-time control can be changed via GLIBC_TUNABLES with
> 
> $ export GLIBC_TUNABLES=glibc.tune.x86_shstk=[permissive|on|off]
> $ export GLIBC_TUNABLES=glibc.tune.x86_ibt=[permissive|on|off]
> 

OK. Thanks for using the x86_* prefix. I've started another thread to see
if everyone wants to namespace per machine so we don't have name collisions.
Using x86_* like you do here avoids any collisions.

> 1. permissive: SHSTK is disabled when dlopening a legacy ELF module.
> 2. on: IBT or SHSTK are always enabled, regardless if there are IBT or
> SHSTK bits in GNU program property.
> 3. off: IBT or SHSTK are always disabled, regardless if there are IBT or
> SHSTK bits in GNU program property.
> 
> <cet.h> from CET-enabled GCC is automatically included by assembly codes
> to add GNU_PROPERTY_X86_FEATURE_1_IBT and GNU_PROPERTY_X86_FEATURE_1_SHSTK
> to GNU program property.  _CET_ENDBR is added at the entrance of all
> assembly functions whose address may be taken.  _CET_NOTRACK is used to
> insert NOTRACK prefix with indirect jump table to support IBT.  It is
> defined as notrack when _CET_NOTRACK is defined in <cet.h>.
> 
> 	 [BZ #21598]
> 	* configure.ac: Add --enable-cet.
> 	* configure: Regenerated.
> 	* elf/Makefille (all-built-dso): Add a comment.
> 	* elf/dl-load.c (filebuf): Moved before "dynamic-link.h".
> 	Include <dl-prop.h>.
> 	(_dl_map_object_from_fd): Call _dl_process_pt_note on PT_NOTE
> 	segment.
> 	* elf/dl-open.c: Include <dl-prop.h>.
> 	(dl_open_worker): Call _dl_open_check.
> 	* elf/rtld.c: Include <dl-prop.h>.
> 	(dl_main): Call _rtld_process_pt_note on PT_NOTE segment.  Call
> 	_rtld_main_check.
> 	* sysdeps/generic/dl-prop.h: New file.
> 	* sysdeps/i386/dl-cet.c: Likewise.
> 	* sysdeps/unix/sysv/linux/x86/cpu-features.c: Likewise.
> 	* sysdeps/unix/sysv/linux/x86/dl-cet.h: Likewise.
> 	* sysdeps/x86/cet-tunables.h: Likewise.
> 	* sysdeps/x86/check-cet.awk: Likewise.
> 	* sysdeps/x86/configure: Likewise.
> 	* sysdeps/x86/configure.ac: Likewise.
> 	* sysdeps/x86/dl-cet.c: Likewise.
> 	* sysdeps/x86/dl-procruntime.c: Likewise.
> 	* sysdeps/x86/dl-prop.h: Likewise.
> 	* sysdeps/x86/libc-start.h: Likewise.
> 	* sysdeps/x86/link_map.h: Likewise.
> 	* sysdeps/i386/dl-trampoline.S (_dl_runtime_resolve): Add
> 	_CET_ENDBR.
> 	(_dl_runtime_profile): Likewise.
> 	(_dl_runtime_resolve_shstk): New.
> 	(_dl_runtime_profile_shstk): Likewise.
> 	* sysdeps/linux/x86/Makefile (sysdep-dl-routines): Add dl-cet
> 	if CET is enabled.
> 	(CFLAGS-.o): Add -fcf-protection if CET is enabled.
> 	(CFLAGS-.os): Likewise.
> 	(CFLAGS-.op): Likewise.
> 	(CFLAGS-.oS): Likewise.
> 	(asm-CPPFLAGS): Add -fcf-protection -include cet.h if CET
> 	is enabled.
> 	(tests-special): Add $(objpfx)check-cet.out.
> 	(cet-built-dso): New.
> 	(+$(cet-built-dso:=.note)): Likewise.
> 	(common-generated): Add $(cet-built-dso:$(common-objpfx)%=%.note).
> 	($(objpfx)check-cet.out): New.
> 	(generated): Add check-cet.out.
> 	* sysdeps/x86/cpu-features.c: Include <dl-cet.h> and
> 	<cet-tunables.h>.
> 	(TUNABLE_CALLBACK (set_x86_ibt)): New prototype.
> 	(TUNABLE_CALLBACK (set_x86_shstk)): Likewise.
> 	(init_cpu_features): Call get_cet_status to check CET status
> 	and update dl_x86_feature_1 with CET status.  Call
> 	TUNABLE_CALLBACK (set_x86_ibt) and TUNABLE_CALLBACK
> 	(set_x86_shstk).  Disable and lock CET in libc.a.
> 	* sysdeps/x86/cpu-tunables.c: Include <cet-tunables.h>.
> 	(TUNABLE_CALLBACK (set_x86_ibt)): New function.
> 	(TUNABLE_CALLBACK (set_x86_shstk)): Likewise.
> 	* sysdeps/x86/sysdep.h (_CET_NOTRACK): New.
> 	(_CET_ENDBR): Define if not defined.
> 	(ENTRY): Add _CET_ENDBR.
> 	* sysdeps/x86/dl-tunables.list (glibc.tune): Add x86_ibt and
> 	x86_shstk.
> 	* sysdeps/x86_64/dl-trampoline.h (_dl_runtime_resolve): Add
> 	_CET_ENDBR.
> 	(_dl_runtime_profile): Likewise.
> ---
>  configure                                  |  11 +
>  configure.ac                               |   6 +
>  elf/Makefile                               |   2 +
>  elf/dl-load.c                              |  60 ++--
>  elf/dl-open.c                              |   3 +
>  elf/rtld.c                                 |   9 +
>  sysdeps/generic/dl-prop.h                  |  47 +++
>  sysdeps/i386/dl-cet.c                      |  67 +++++
>  sysdeps/i386/dl-trampoline.S               |  72 +++++
>  sysdeps/unix/sysv/linux/x86/cpu-features.c |  38 +++
>  sysdeps/unix/sysv/linux/x86/dl-cet.h       |  34 +++
>  sysdeps/x86/Makefile                       |  42 +++
>  sysdeps/x86/cet-tunables.h                 |  29 ++
>  sysdeps/x86/check-cet.awk                  |  53 ++++
>  sysdeps/x86/configure                      |  69 +++++
>  sysdeps/x86/configure.ac                   |  46 +++
>  sysdeps/x86/cpu-features.c                 |  60 ++++
>  sysdeps/x86/cpu-tunables.c                 |  48 +++
>  sysdeps/x86/dl-cet.c                       | 335 +++++++++++++++++++++
>  sysdeps/x86/dl-procruntime.c               |  68 +++++
>  sysdeps/x86/dl-prop.h                      | 153 ++++++++++
>  sysdeps/x86/dl-tunables.list               |   6 +
>  sysdeps/x86/libc-start.h                   |  25 ++
>  sysdeps/x86/link_map.h                     |  26 ++
>  sysdeps/x86/sysdep.h                       |   8 +
>  sysdeps/x86_64/dl-trampoline.h             |   2 +
>  26 files changed, 1294 insertions(+), 25 deletions(-)
>  create mode 100644 sysdeps/generic/dl-prop.h
>  create mode 100644 sysdeps/i386/dl-cet.c
>  create mode 100644 sysdeps/unix/sysv/linux/x86/cpu-features.c
>  create mode 100644 sysdeps/unix/sysv/linux/x86/dl-cet.h
>  create mode 100644 sysdeps/x86/cet-tunables.h
>  create mode 100644 sysdeps/x86/check-cet.awk
>  create mode 100644 sysdeps/x86/configure
>  create mode 100644 sysdeps/x86/configure.ac
>  create mode 100644 sysdeps/x86/dl-cet.c
>  create mode 100644 sysdeps/x86/dl-procruntime.c
>  create mode 100644 sysdeps/x86/dl-prop.h
>  create mode 100644 sysdeps/x86/libc-start.h
>  create mode 100644 sysdeps/x86/link_map.h
> 

[snip configure]

> diff --git a/configure.ac b/configure.ac
> index f41ed6decb..014e09a5d5 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -464,6 +464,12 @@ AC_ARG_ENABLE([mathvec],
>  	      [build_mathvec=$enableval],
>  	      [build_mathvec=notset])
>  
> +AC_ARG_ENABLE([cet],
> +	      AC_HELP_STRING([--enable-cet],
> +			     [enable Intel Control-flow Enforcement Technology (CET), x86 only]),
> +	      [enable_cet=$enableval],
> +	      [enable_cet=no])
> +

OK.

>  # We keep the original values in `$config_*' and never modify them, so we
>  # can write them unchanged into config.make.  Everything else uses
>  # $machine, $vendor, and $os, and changes them whenever convenient.
> diff --git a/elf/Makefile b/elf/Makefile
> index 41cc3681be..84107f6dbb 100644
> --- a/elf/Makefile
> +++ b/elf/Makefile
> @@ -1058,6 +1058,8 @@ $(objpfx)tst-piemod1.so: $(libsupport)
>  $(objpfx)tst-pie1: $(objpfx)tst-piemod1.so
>  
>  ifeq (yes,$(build-shared))
> +# NB: Please keep cet-built-dso in sysdeps/x86/Makefile in sync with
> +# all-built-dso here.

OK. Perfect. Thanks for this.

>  all-built-dso := $(common-objpfx)elf/ld.so $(common-objpfx)libc.so \
>  		 $(filter-out $(common-objpfx)linkobj/libc.so, \
>  			      $(sort $(wildcard $(addprefix $(common-objpfx), \
> diff --git a/elf/dl-load.c b/elf/dl-load.c
> index 09185ab68d..c51e4b3718 100644
> --- a/elf/dl-load.c
> +++ b/elf/dl-load.c
> @@ -30,6 +30,32 @@
>  #include <sys/param.h>
>  #include <sys/stat.h>
>  #include <sys/types.h>
> +
> +/* Type for the buffer we put the ELF header and hopefully the program
> +   header.  This buffer does not really have to be too large.  In most
> +   cases the program header follows the ELF header directly.  If this
> +   is not the case all bets are off and we can make the header
> +   arbitrarily large and still won't get it read.  This means the only
> +   question is how large are the ELF and program header combined.  The
> +   ELF header 32-bit files is 52 bytes long and in 64-bit files is 64
> +   bytes long.  Each program header entry is again 32 and 56 bytes
> +   long respectively.  I.e., even with a file which has 10 program
> +   header entries we only have to read 372B/624B respectively.  Add to
> +   this a bit of margin for program notes and reading 512B and 832B
> +   for 32-bit and 64-bit files respecitvely is enough.  If this
> +   heuristic should really fail for some file the code in
> +   `_dl_map_object_from_fd' knows how to recover.  */
> +struct filebuf
> +{
> +  ssize_t len;
> +#if __WORDSIZE == 32
> +# define FILEBUF_SIZE 512
> +#else
> +# define FILEBUF_SIZE 832
> +#endif
> +  char buf[FILEBUF_SIZE] __attribute__ ((aligned (__alignof (ElfW(Ehdr)))));
> +};
> +

OK.

>  #include "dynamic-link.h"
>  #include <abi-tag.h>
>  #include <stackinfo.h>
> @@ -44,6 +70,7 @@
>  #include <dl-unmap-segments.h>
>  #include <dl-machine-reject-phdr.h>
>  #include <dl-sysdep-open.h>
> +#include <dl-prop.h>
>  #include <not-cancel.h>
>  
>  #include <endian.h>
> @@ -69,31 +96,6 @@ int __stack_prot attribute_hidden attribute_relro
>  #endif
>  
>  
> -/* Type for the buffer we put the ELF header and hopefully the program
> -   header.  This buffer does not really have to be too large.  In most
> -   cases the program header follows the ELF header directly.  If this
> -   is not the case all bets are off and we can make the header
> -   arbitrarily large and still won't get it read.  This means the only
> -   question is how large are the ELF and program header combined.  The
> -   ELF header 32-bit files is 52 bytes long and in 64-bit files is 64
> -   bytes long.  Each program header entry is again 32 and 56 bytes
> -   long respectively.  I.e., even with a file which has 10 program
> -   header entries we only have to read 372B/624B respectively.  Add to
> -   this a bit of margin for program notes and reading 512B and 832B
> -   for 32-bit and 64-bit files respecitvely is enough.  If this
> -   heuristic should really fail for some file the code in
> -   `_dl_map_object_from_fd' knows how to recover.  */
> -struct filebuf
> -{
> -  ssize_t len;
> -#if __WORDSIZE == 32
> -# define FILEBUF_SIZE 512
> -#else
> -# define FILEBUF_SIZE 832
> -#endif
> -  char buf[FILEBUF_SIZE] __attribute__ ((aligned (__alignof (ElfW(Ehdr)))));
> -};
> -
>  /* This is the decomposed LD_LIBRARY_PATH search path.  */
>  static struct r_search_path_struct env_path_list attribute_relro;
>  
> @@ -1152,6 +1154,14 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
>  	  l->l_relro_addr = ph->p_vaddr;
>  	  l->l_relro_size = ph->p_memsz;
>  	  break;
> +
> +	case PT_NOTE:
> +	  if (_dl_process_pt_note (l, ph, fd, fbp))
> +	    {
> +	      errstring = N_("cannot process note segment");
> +	      goto call_lose;
> +	    }
> +	  break;

OK.

>  	}
>  
>      if (__glibc_unlikely (nloadcmds == 0))
> diff --git a/elf/dl-open.c b/elf/dl-open.c
> index 9dde4acfbc..f6c8ef1043 100644
> --- a/elf/dl-open.c
> +++ b/elf/dl-open.c
> @@ -35,6 +35,7 @@
>  #include <libc-internal.h>
>  
>  #include <dl-dst.h>
> +#include <dl-prop.h>

OK.

>  
>  
>  /* We must be careful not to leave us in an inconsistent state.  Thus we
> @@ -291,6 +292,8 @@ dl_open_worker (void *a)
>    _dl_debug_state ();
>    LIBC_PROBE (map_complete, 3, args->nsid, r, new);
>  
> +  _dl_open_check (new);

OK. Better. Less bitrot with unconditional calls like this.

> +
>    /* Print scope information.  */
>    if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
>      _dl_show_scope (new, 0);
> diff --git a/elf/rtld.c b/elf/rtld.c
> index 8c732adb68..1b0c74739f 100644
> --- a/elf/rtld.c
> +++ b/elf/rtld.c
> @@ -38,6 +38,7 @@
>  #include <dl-cache.h>
>  #include <dl-osinfo.h>
>  #include <dl-procinfo.h>
> +#include <dl-prop.h>

OK.

>  #include <tls.h>
>  #include <stap-probe.h>
>  #include <stackinfo.h>
> @@ -1241,6 +1242,12 @@ of this helper program; chances are you did not intend to run this program.\n\
>  	main_map->l_relro_addr = ph->p_vaddr;
>  	main_map->l_relro_size = ph->p_memsz;
>  	break;
> +
> +      case PT_NOTE:
> +	if (_rtld_process_pt_note (main_map, ph))
> +	  _dl_error_printf ("\
> +ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
> +	break;

OK. Thanks for the direct call.

>        }
>  
>    /* Adjust the address of the TLS initialization image in case
> @@ -2110,6 +2117,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
>  	_dl_show_scope (l, 0);
>      }
>  
> +  _rtld_main_check (main_map, _dl_argv[0]);

OK. Likewise.

> +
>    if (prelinked)
>      {
>        if (main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL)
> diff --git a/sysdeps/generic/dl-prop.h b/sysdeps/generic/dl-prop.h
> new file mode 100644
> index 0000000000..e5fe5d23aa
> --- /dev/null
> +++ b/sysdeps/generic/dl-prop.h
> @@ -0,0 +1,47 @@
> +/* Support for GNU properties.  Generic version.
> +   Copyright (C) 2018 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef _DL_PROP_H
> +#define _DL_PROP_H
> +

Suggest adding the following comment:

/* The following functions are used by the dynamic loader and
   the dlopen machinery to process PT_NOTE entries in the binary
   or shared object.  The notes can be used to change the behaviour
   of the loader, and as such offer a flexible mechanism for hooking
   in various checks related to ABI tags or implementing "flag day"
   ABI transitions.  */

> +static inline void __attribute__ ((always_inline))
> +_rtld_main_check (struct link_map *m, const char *program)
> +{
> +}
> +
> +static inline void __attribute__ ((always_inline))
> +_dl_open_check (struct link_map *m)
> +{
> +}
> +
> +#ifdef FILEBUF_SIZE
> +static inline int __attribute__ ((always_inline))
> +_dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph,
> +		     int fd, struct filebuf *fbp)
> +{
> +  return 0;
> +}
> +#endif
> +
> +static inline int __attribute__ ((always_inline))
> +_rtld_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph)
> +{
> +  return 0;
> +}

OK.

> +
> +#endif /* _DL_PROP_H */
> diff --git a/sysdeps/i386/dl-cet.c b/sysdeps/i386/dl-cet.c
> new file mode 100644
> index 0000000000..5d9a4e8d51
> --- /dev/null
> +++ b/sysdeps/i386/dl-cet.c
> @@ -0,0 +1,67 @@
> +/* Linux/i386 CET initializers function.
> +   Copyright (C) 2018 Free Software Foundation, Inc.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +
> +#define LINKAGE static inline
> +#define _dl_cet_check cet_check
> +#include <sysdeps/x86/dl-cet.c>
> +#undef _dl_cet_check
> +
> +#ifdef SHARED
> +void
> +_dl_cet_check (struct link_map *main_map, const char *program)
> +{
> +  cet_check (main_map, program);
> +
> +  if ((GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
> +    {
> +      /* Replace _dl_runtime_resolve and _dl_runtime_profile with
> +         _dl_runtime_resolve_shstk and _dl_runtime_profile_shstk,
> +	 respectively if SHSTK is enabled.  */
> +      extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden;
> +      extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden;
> +      extern void _dl_runtime_profile (Elf32_Word) attribute_hidden;
> +      extern void _dl_runtime_profile_shstk (Elf32_Word) attribute_hidden;
> +      unsigned int i;
> +      struct link_map *l;
> +      Elf32_Addr *got;
> +
> +      if (main_map->l_info[DT_JMPREL])
> +	{
> +	  got = (Elf32_Addr *) D_PTR (main_map, l_info[DT_PLTGOT]);
> +	  if (got[2] == (Elf32_Addr) &_dl_runtime_resolve)
> +	    got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk;
> +	  else if (got[2] == (Elf32_Addr) &_dl_runtime_profile)
> +	    got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk;
> +	}

OK.

> +
> +      i = main_map->l_searchlist.r_nlist;
> +      while (i-- > 0)
> +	{
> +	  l = main_map->l_initfini[i];
> +	  if (l->l_info[DT_JMPREL])
> +	    {
> +	      got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
> +	      if (got[2] == (Elf32_Addr) &_dl_runtime_resolve)
> +		got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk;
> +	      else if (got[2] == (Elf32_Addr) &_dl_runtime_profile)
> +		got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk;

OK.

> +	    }
> +	}
> +    }
> +}

OK.

> +#endif
> diff --git a/sysdeps/i386/dl-trampoline.S b/sysdeps/i386/dl-trampoline.S
> index 8bf86f8fd9..6dc0319216 100644
> --- a/sysdeps/i386/dl-trampoline.S
> +++ b/sysdeps/i386/dl-trampoline.S
> @@ -32,6 +32,7 @@
>  	.align 16
>  _dl_runtime_resolve:
>  	cfi_adjust_cfa_offset (8)
> +	_CET_ENDBR

OK.

>  	pushl %eax		# Preserve registers otherwise clobbered.
>  	cfi_adjust_cfa_offset (4)
>  	pushl %ecx
> @@ -50,14 +51,85 @@ _dl_runtime_resolve:
>  	cfi_endproc
>  	.size _dl_runtime_resolve, .-_dl_runtime_resolve
>  
> +# The SHSTK compatible version.
> +	.text
> +	.globl _dl_runtime_resolve_shstk
> +	.type _dl_runtime_resolve_shstk, @function
> +	cfi_startproc
> +	.align 16
> +_dl_runtime_resolve_shstk:
> +	cfi_adjust_cfa_offset (8)
> +	_CET_ENDBR
> +	pushl %eax		# Preserve registers otherwise clobbered.
> +	cfi_adjust_cfa_offset (4)
> +	pushl %edx
> +	cfi_adjust_cfa_offset (4)
> +	movl 12(%esp), %edx	# Copy args pushed by PLT in register.  Note
> +	movl 8(%esp), %eax	# that `fixup' takes its parameters in regs.
> +	call _dl_fixup		# Call resolver.
> +	movl (%esp), %edx	# Get register content back.
> +	movl %eax, %ecx		# Store the function address.
> +	movl 4(%esp), %eax	# Get register content back.
> +	addl $16, %esp		# Adjust stack: PLT1 + PLT2 + %eax + %edx
> +	cfi_adjust_cfa_offset (-16)
> +	jmp *%ecx		# Jump to function address.
> +	cfi_endproc
> +	.size _dl_runtime_resolve_shstk, .-_dl_runtime_resolve_shstk

OK.

>  
>  #ifndef PROF
> +# The SHSTK compatible version.
> +	.globl _dl_runtime_profile_shstk
> +	.type _dl_runtime_profile_shstk, @function
> +	cfi_startproc
> +	.align 16
> +_dl_runtime_profile_shstk:
> +	cfi_adjust_cfa_offset (8)
> +	_CET_ENDBR
> +	pushl %esp
> +	cfi_adjust_cfa_offset (4)
> +	addl $8, (%esp)		# Account for the pushed PLT data
> +	pushl %ebp
> +	cfi_adjust_cfa_offset (4)
> +	pushl %eax		# Preserve registers otherwise clobbered.
> +	cfi_adjust_cfa_offset (4)
> +	pushl %ecx
> +	cfi_adjust_cfa_offset (4)
> +	pushl %edx
> +	cfi_adjust_cfa_offset (4)
> +	movl %esp, %ecx
> +	subl $8, %esp
> +	cfi_adjust_cfa_offset (8)
> +	movl $-1, 4(%esp)
> +	leal 4(%esp), %edx
> +	movl %edx, (%esp)
> +	pushl %ecx		# Address of the register structure
> +	cfi_adjust_cfa_offset (4)
> +	movl 40(%esp), %ecx	# Load return address
> +	movl 36(%esp), %edx	# Copy args pushed by PLT in register.  Note
> +	movl 32(%esp), %eax	# that `fixup' takes its parameters in regs.
> +	call _dl_profile_fixup	# Call resolver.
> +	cfi_adjust_cfa_offset (-8)
> +	movl (%esp), %edx
> +	testl %edx, %edx
> +	jns 1f
> +	movl 4(%esp), %edx	# Get register content back.
> +	movl %eax, %ecx		# Store the function address.
> +	movl 12(%esp), %eax	# Get register content back.
> +	# Adjust stack: PLT1 + PLT2 + %esp + %ebp + %eax + %ecx + %edx
> +	# + free.
> +	addl $32, %esp
> +	cfi_adjust_cfa_offset (-32)
> +	jmp *%ecx		# Jump to function address.
> +	cfi_endproc
> +	.size _dl_runtime_profile_shstk, .-_dl_runtime_profile_shstk
> +

OK.

>  	.globl _dl_runtime_profile
>  	.type _dl_runtime_profile, @function
>  	cfi_startproc
>  	.align 16
>  _dl_runtime_profile:
>  	cfi_adjust_cfa_offset (8)
> +	_CET_ENDBR

OK.

>  	pushl %esp
>  	cfi_adjust_cfa_offset (4)
>  	addl $8, (%esp)		# Account for the pushed PLT data
> diff --git a/sysdeps/unix/sysv/linux/x86/cpu-features.c b/sysdeps/unix/sysv/linux/x86/cpu-features.c
> new file mode 100644
> index 0000000000..0045f979da
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/cpu-features.c
> @@ -0,0 +1,38 @@
> +/* Initialize CPU feature data for Linux/x86.
> +   This file is part of the GNU C Library.
> +   Copyright (C) 2018 Free Software Foundation, Inc.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifdef __CET__
> +static inline int __attribute__ ((always_inline))
> +get_cet_status (void)
> +{
> +  return 0;
> +}

Why is this still "return 0;" ? Is it because the kernel pieces aren't
completely done yet and we'll enable this later?

> +
> +# ifndef SHARED
> +static inline void
> +x86_setup_tls (void)
> +{
> +  __libc_setup_tls ();
> +  THREAD_SETMEM (THREAD_SELF, header.feature_1, GL(dl_x86_feature_1)[0]);
> +}
> +
> +#  define ARCH_SETUP_TLS() x86_setup_tls ()
> +# endif
> +#endif
> +

OK.

> +#include <sysdeps/x86/cpu-features.c>
> diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h
> new file mode 100644
> index 0000000000..9903bbe41f
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h
> @@ -0,0 +1,34 @@
> +/* Linux/x86 CET initializers function.
> +   Copyright (C) 2018 Free Software Foundation, Inc.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +static inline int __attribute__ ((always_inline))
> +dl_cet_allocate_legacy_bitmap (unsigned long *legacy_bitmap)
> +{
> +  return -1;
> +}
> +
> +static inline int __attribute__ ((always_inline))
> +dl_cet_disable_cet (unsigned int cet_feature)
> +{
> +  return -1;
> +}
> +
> +static inline int __attribute__ ((always_inline))
> +dl_cet_lock_cet (void)
> +{
> +  return -1;
> +}

All three of these need comments explaining why they just return -1.
Is it because it's a temporary implementation and the kernel pieces
are not yet complete? It should say so then.

> diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
> index 65292f4032..e9b2d0b35d 100644
> --- a/sysdeps/x86/Makefile
> +++ b/sysdeps/x86/Makefile
> @@ -13,3 +13,45 @@ ifeq ($(subdir),setjmp)
>  gen-as-const-headers += jmp_buf-ssp.sym
>  sysdep_routines += __longjmp_cancel
>  endif
> +
> +ifeq ($(enable-cet),yes)
> +ifeq ($(subdir),elf)
> +sysdep-dl-routines += dl-cet

OK. Inlcudes dl-cet.c code.

> +endif
> +
> +# Add -fcf-protection to CFLAGS when CET is enabled.
> +CFLAGS-.o += -fcf-protection
> +CFLAGS-.os += -fcf-protection
> +CFLAGS-.op += -fcf-protection
> +CFLAGS-.oS += -fcf-protection
> +
> +# Compile assembly codes with <cet.h> when CET is enabled.
> +asm-CPPFLAGS += -fcf-protection -include cet.h
> +
> +ifeq ($(subdir),elf)
> +ifeq (yes,$(build-shared))
> +tests-special += $(objpfx)check-cet.out
> +endif
> +
> +# FIXME: Can't use all-built-dso in elf/Makefile since this file is
> +# processed before elf/Makefile.  Duplicate it here.

OK.

> +cet-built-dso := $(common-objpfx)elf/ld.so $(common-objpfx)libc.so \
> +		 $(filter-out $(common-objpfx)linkobj/libc.so, \
> +			      $(sort $(wildcard $(addprefix $(common-objpfx), \
> +							    */lib*.so \
> +							    iconvdata/*.so))))
> +
> +$(cet-built-dso:=.note): %.note: %
> +	@rm -f $@T
> +	LC_ALL=C $(READELF) -n $< > $@T
> +	test -s $@T
> +	mv -f $@T $@
> +common-generated += $(cet-built-dso:$(common-objpfx)%=%.note)
> +
> +$(objpfx)check-cet.out: $(..)sysdeps/x86/check-cet.awk \
> +			$(cet-built-dso:=.note)
> +	LC_ALL=C $(AWK) -f $^ > $@; \
> +	$(evaluate-test)
> +generated += check-cet.out
> +endif
> +endif
> diff --git a/sysdeps/x86/cet-tunables.h b/sysdeps/x86/cet-tunables.h
> new file mode 100644
> index 0000000000..ca023053ee
> --- /dev/null
> +++ b/sysdeps/x86/cet-tunables.h
> @@ -0,0 +1,29 @@
> +/* x86 CET tuning.
> +   This file is part of the GNU C Library.
> +   Copyright (C) 2018 Free Software Foundation, Inc.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* Valid control values:
> +   0: Enable CET features based on ELF property note.
> +   1: Always disable CET features.
> +   2: Always enable CET features.
> +   3: Enable CET features permissively.
> + */
> +#define CET_ELF_PROPERTY	0
> +#define CET_ALWAYS_OFF		1
> +#define CET_ALWAYS_ON		2
> +#define CET_PERMISSIVE		3
> +#define CET_MAX			CET_PERMISSIVE

OK.

> diff --git a/sysdeps/x86/check-cet.awk b/sysdeps/x86/check-cet.awk
> new file mode 100644
> index 0000000000..380d998caf
> --- /dev/null
> +++ b/sysdeps/x86/check-cet.awk
> @@ -0,0 +1,53 @@
> +# Verify that all shared objects contain the CET property.
> +# Copyright (C) 2018 Free Software Foundation, Inc.
> +# This file is part of the GNU C Library.
> +#
> +# The GNU C Library is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU Lesser General Public
> +# License as published by the Free Software Foundation; either
> +# version 2.1 of the License, or (at your option) any later version.
> +#
> +# The GNU C Library is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +# Lesser General Public License for more details.
> +#
> +# You should have received a copy of the GNU Lesser General Public
> +# License along with the GNU C Library; if not, see
> +# <http://www.gnu.org/licenses/>.
> +
> +# This awk script expects to get command-line files that are each
> +# the output of 'readelf -n' on a single shared object.
> +# It exits successfully (0) if all of them contained the CET property.
> +# It fails (1) if any didn't contain the CET property
> +# It fails (2) if the input did not take the expected form.
> +
> +BEGIN { result = cet = sanity = 0 }
> +
> +function check_one(name) {
> +  if (!sanity) {
> +    print name ": *** input did not look like readelf -n output";
> +    result = 2;
> +  } else if (cet) {
> +    print name ": OK";
> +  } else {
> +    print name ": *** no CET property found";
> +    result = result ? result : 1;
> +  }
> +
> +  cet = sanity = 0;
> +}
> +
> +FILENAME != lastfile {
> +  if (lastfile)
> +    check_one(lastfile);
> +  lastfile = FILENAME;
> +}
> +
> +index ($0, "Displaying notes") != 0 { sanity = 1 }
> +index ($0, "IBT") != 0 && index ($0, "SHSTK") != 0 { cet = 1 }
> +
> +END {
> +  check_one(lastfile);
> +  exit(result);
> +}

OK.

> diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure
[snipped]

> diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac
> new file mode 100644
> index 0000000000..a909b073af
> --- /dev/null
> +++ b/sysdeps/x86/configure.ac
> @@ -0,0 +1,46 @@
> +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
> +# Local configure fragment for sysdeps/x86.
> +
> +if test x"$enable_cet" = xyes; then
> +  # Check if CET can be enabled.
> +  AC_CACHE_CHECK(whether CET can be enabled,
> +		 libc_cv_x86_cet_available, [dnl
> +cat > conftest.c <<EOF
> +#if !defined __CET__ || __CET__ != 3
> +# error CET isn't available.
> +#endif
> +EOF
> +		 if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS -fcf-protection -include cet.h conftest.c 1>&AS_MESSAGE_LOG_FD); then
> +		   libc_cv_x86_cet_available=yes
> +		 else
> +		   libc_cv_x86_cet_available=no
> +		 fi
> +		 rm -rf conftest*])
> +  if test $libc_cv_x86_cet_available = yes; then
> +    enable_cet=yes
> +  else
> +    if test x"$enable_cet" = xdefault; then
> +      enable_cet=no
> +    else
> +      AC_MSG_ERROR([$CC doesn't support CET])
> +    fi
> +  fi
> +fi
> +if test $enable_cet = yes; then
> +  # Check if assembler supports CET.
> +  AC_CACHE_CHECK(whether $AS supports CET,
> +		 libc_cv_x86_cet_as, [dnl
> +cat > conftest.s <<EOF
> +	incsspd %ecx
> +EOF
> +		 if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s -o conftest.o 1>&AS_MESSAGE_LOG_FD); then
> +		   libc_cv_x86_cet_as=yes
> +		 else
> +		   libc_cv_x86_cet_as=no
> +		 fi
> +		 rm -rf conftest*])
> +  if test $libc_cv_x86_cet_as = no; then
> +    AC_MSG_ERROR([$AS doesn't support CET])
> +  fi
> +fi
> +LIBC_CONFIG_VAR([enable-cet], [$enable_cet])

OK.

> diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
> index d41ebde823..f52e28e04b 100644
> --- a/sysdeps/x86/cpu-features.c
> +++ b/sysdeps/x86/cpu-features.c
> @@ -28,6 +28,15 @@
>  
>  extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *)
>    attribute_hidden;
> +
> +# ifdef __CET__
> +#  include <dl-cet.h>
> +#  include <cet-tunables.h>
> +extern void TUNABLE_CALLBACK (set_x86_ibt) (tunable_val_t *)
> +  attribute_hidden;
> +extern void TUNABLE_CALLBACK (set_x86_shstk) (tunable_val_t *)
> +  attribute_hidden;
> +# endif

OK.

>  #endif
>  
>  static void
> @@ -449,4 +458,55 @@ no_cpuid:
>    else if (CPU_FEATURES_ARCH_P (cpu_features, I586))
>      GLRO(dl_platform) = "i586";
>  #endif
> +
> +#ifdef __CET__
> +# if HAVE_TUNABLES
> +  TUNABLE_GET (x86_ibt, tunable_val_t *,
> +	       TUNABLE_CALLBACK (set_x86_ibt));
> +  TUNABLE_GET (x86_shstk, tunable_val_t *,
> +	       TUNABLE_CALLBACK (set_x86_shstk));

OK.

> +# endif
> +
> +  /* Check CET status.  */
> +  unsigned int cet_status = get_cet_status ();

OK.

> +
> +  if (cet_status)
> +    {
> +      GL(dl_x86_feature_1)[0] = cet_status;
> +
> +# ifndef SHARED
> +      /* Check if IBT and SHSTK are enabled by kernel.  */
> +      if ((cet_status & GNU_PROPERTY_X86_FEATURE_1_IBT)
> +	  || (cet_status & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
> +	{
> +	  /* Disable IBT and/or SHSTK if they are enabled by kernel, but
> +	     disabled by environment variable:
> +
> +	     GLIBC_TUNABLES=glibc.tune.hwcaps=-IBT,-SHSTK

OK.

> +	   */
> +	  unsigned int cet_feature = 0;
> +	  if (!HAS_CPU_FEATURE (IBT))
> +	    cet_feature |= GNU_PROPERTY_X86_FEATURE_1_IBT;
> +	  if (!HAS_CPU_FEATURE (SHSTK))
> +	    cet_feature |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
> +
> +	  if (cet_feature)
> +	    {
> +	      int res = dl_cet_disable_cet (cet_feature);
> +
> +	      /* Clear the disabled bits in dl_x86_feature_1.  */
> +	      if (res == 0)
> +		GL(dl_x86_feature_1)[0] &= ~cet_feature;
> +	    }
> +
> +	  /* Lock CET if IBT or SHSTK is enabled in executable.  Don't
> +	     lock CET if SHSTK is enabled permissively.  */
> +	  if (((GL(dl_x86_feature_1)[1] >> CET_MAX)
> +	       & ((1 << CET_MAX) - 1))
> +	       != CET_PERMISSIVE)
> +	    dl_cet_lock_cet ();
> +	}
> +# endif
> +    }
> +#endif

OK.

>  }
> diff --git a/sysdeps/x86/cpu-tunables.c b/sysdeps/x86/cpu-tunables.c
> index af761dcbbc..a5c0153348 100644
> --- a/sysdeps/x86/cpu-tunables.c
> +++ b/sysdeps/x86/cpu-tunables.c
> @@ -334,4 +334,52 @@ TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *valp)
>      }
>    while (*p != '\0');
>  }
> +
> +# ifdef __CET__
> +#  include <cet-tunables.h>
> +
> +attribute_hidden
> +void
> +TUNABLE_CALLBACK (set_x86_ibt) (tunable_val_t *valp)
> +{
> +  if (DEFAULT_MEMCMP (valp->strval, "on", sizeof ("on")) == 0)
> +    {
> +      GL(dl_x86_feature_1)[1] &= ~((1 << CET_MAX) - 1);
> +      GL(dl_x86_feature_1)[1] |= CET_ALWAYS_ON;
> +    }
> +  else if (DEFAULT_MEMCMP (valp->strval, "off", sizeof ("off")) == 0)
> +    {
> +      GL(dl_x86_feature_1)[1] &= ~((1 << CET_MAX) - 1);
> +      GL(dl_x86_feature_1)[1] |= CET_ALWAYS_OFF;
> +    }
> +  else if (DEFAULT_MEMCMP (valp->strval, "permissive",
> +			   sizeof ("permissive")) == 0)
> +    {
> +      GL(dl_x86_feature_1)[1] &= ~((1 << CET_MAX) - 1);
> +      GL(dl_x86_feature_1)[1] |= CET_PERMISSIVE;
> +    }
> +}

OK.

> +
> +attribute_hidden
> +void
> +TUNABLE_CALLBACK (set_x86_shstk) (tunable_val_t *valp)
> +{
> +  if (DEFAULT_MEMCMP (valp->strval, "on", sizeof ("on")) == 0)
> +    {
> +      GL(dl_x86_feature_1)[1] &= ~(((1 << CET_MAX) - 1) << CET_MAX);
> +      GL(dl_x86_feature_1)[1] |= (CET_ALWAYS_ON << CET_MAX);
> +    }
> +  else if (DEFAULT_MEMCMP (valp->strval, "off", sizeof ("off")) == 0)
> +    {
> +      GL(dl_x86_feature_1)[1] &= ~(((1 << CET_MAX) - 1) << CET_MAX);
> +      GL(dl_x86_feature_1)[1] |= (CET_ALWAYS_OFF << CET_MAX);
> +    }
> +  else if (DEFAULT_MEMCMP (valp->strval, "permissive",
> +			   sizeof ("permissive")) == 0)
> +    {
> +      GL(dl_x86_feature_1)[1] &= ~(((1 << CET_MAX) - 1) << CET_MAX);
> +      GL(dl_x86_feature_1)[1] |= (CET_PERMISSIVE << CET_MAX);
> +    }
> +}

OK.

> +# endif
>  #endif
> diff --git a/sysdeps/x86/dl-cet.c b/sysdeps/x86/dl-cet.c
> new file mode 100644
> index 0000000000..5018e4560d
> --- /dev/null
> +++ b/sysdeps/x86/dl-cet.c
> @@ -0,0 +1,335 @@
> +/* x86 CET initializers function.
> +   Copyright (C) 2018 Free Software Foundation, Inc.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <unistd.h>
> +#include <errno.h>
> +#include <libintl.h>
> +#include <ldsodefs.h>
> +#include <dl-cet.h>
> +#include <cet-tunables.h>
> +
> +static int
> +dl_cet_mark_legacy_region (struct link_map *l)
> +{
> +  /* Mark PT_LOAD segments with PF_X in legacy code page bitmap.  */
> +  size_t i, phnum = l->l_phnum;
> +  const ElfW(Phdr) *phdr = l->l_phdr;
> +#ifdef __x86_64__
> +  typedef unsigned long long word_t;
> +#else
> +  typedef unsigned long word_t;
> +#endif
> +  unsigned int bits_to_set;
> +  word_t mask_to_set;
> +#define BITS_PER_WORD (sizeof (word_t) * 8)
> +#define BITMAP_FIRST_WORD_MASK(start) \
> +  (~((word_t) 0) << ((start) & (BITS_PER_WORD - 1)))
> +#define BITMAP_LAST_WORD_MASK(nbits) \
> +  (~((word_t) 0) >> (-(nbits) & (BITS_PER_WORD - 1)))
> +
> +  word_t *bitmap = (word_t *) GL(dl_x86_legacy_bitmap)[0];
> +  word_t bitmap_size = GL(dl_x86_legacy_bitmap)[1];
> +  word_t *p;
> +  size_t page_size = GLRO(dl_pagesize);
> +
> +  for (i = 0; i < phnum; i++)
> +    if (phdr[i].p_type == PT_LOAD && (phdr[i].p_flags & PF_X))
> +      {
> +	/* One bit in legacy bitmap represents a page.  */
> +	ElfW(Addr) start = (phdr[i].p_vaddr + l->l_addr) / page_size;
> +	ElfW(Addr) len = (phdr[i].p_memsz + page_size - 1) / page_size;
> +	ElfW(Addr) end = start + len;
> +
> +	if ((end / 8) > bitmap_size)
> +	  return -EFAULT;

Why return -EFAULT? We only check != 0 in the caller, so just return -1?
It may conuse things by using errno here, and worse negative errno.

Please just return -1.

> +
> +	p = bitmap + (start / BITS_PER_WORD);
> +	bits_to_set = BITS_PER_WORD - (start % BITS_PER_WORD);
> +	mask_to_set = BITMAP_FIRST_WORD_MASK (start);
> +
> +	while (len >= bits_to_set)
> +	  {
> +	    *p |= mask_to_set;

OK.

> +	    len -= bits_to_set;
> +	    bits_to_set = BITS_PER_WORD;
> +	    mask_to_set = ~((word_t) 0);
> +	    p++;
> +	  }
> +	if (len)
> +	  {
> +	    mask_to_set &= BITMAP_LAST_WORD_MASK (end);
> +	    *p |= mask_to_set;

OK.

> +	  }
> +      }
> +
> +  return 0;
> +}
> +
> +/* Check if object M is compatible with CET.  */
> +
> +static void
> +dl_cet_check (struct link_map *m, const char *program)
> +{
> +  /* Check how IBT should be enabled.  */
> +  unsigned int enable_ibt_type
> +    = GL(dl_x86_feature_1)[1] & ((1 << CET_MAX) - 1);
> +  /* Check how SHSTK should be enabled.  */
> +  unsigned int enable_shstk_type
> +    = ((GL(dl_x86_feature_1)[1] >> CET_MAX) & ((1 << CET_MAX) - 1));
> +
> +  /* No legacy object check if both IBT and SHSTK are always on.  */
> +  if (enable_ibt_type == CET_ALWAYS_ON
> +      && enable_shstk_type == CET_ALWAYS_ON)
> +    return;
> +
> +  /* Check if IBT is enabled by kernel.  */
> +  bool ibt_enabled
> +    = (GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0;
> +  /* Check if SHSTK is enabled by kernel.  */
> +  bool shstk_enabled
> +    = (GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0;
> +
> +  if (ibt_enabled || shstk_enabled)
> +    {
> +      struct link_map *l = NULL;
> +
> +      /* Check if IBT and SHSTK are enabled in object.  */
> +      bool enable_ibt = (ibt_enabled
> +			 && enable_ibt_type != CET_ALWAYS_OFF);
> +      bool enable_shstk = (shstk_enabled
> +			   && enable_shstk_type != CET_ALWAYS_OFF);
> +      if (program)
> +	{
> +	  /* Enable IBT and SHSTK only if they are enabled in executable.
> +	     NB: IBT and SHSTK may be disabled by environment variable:
> +
> +	     GLIBC_TUNABLES=glibc.tune.hwcaps=-IBT,-SHSTK
> +	   */
> +	  enable_ibt &= (HAS_CPU_FEATURE (IBT)
> +			 && (enable_ibt_type == CET_ALWAYS_ON
> +			     || (m->l_cet & lc_ibt) != 0));
> +	  enable_shstk &= (HAS_CPU_FEATURE (SHSTK)
> +			   && (enable_shstk_type == CET_ALWAYS_ON
> +			       || (m->l_cet & lc_shstk) != 0));
> +	}
> +
> +      /* ld.so is CET-enabled by kernel.  But shared objects may not
> +	 support IBT nor SHSTK.  */
> +      if (enable_ibt || enable_shstk)
> +	{
> +	  int res;
> +	  unsigned int i;
> +	  unsigned int first_legacy, last_legacy;
> +	  bool need_legacy_bitmap = false;
> +
> +	  i = m->l_searchlist.r_nlist;
> +	  while (i-- > 0)
> +	    {
> +	      /* Check each shared object to see if IBT and SHSTK are
> +		 enabled.  */
> +	      l = m->l_initfini[i];
> +
> +	      if (l->l_init_called)
> +		continue;
> +
> +#ifdef SHARED
> +	      /* Skip CET check for ld.so since ld.so is CET-enabled.
> +		 CET will be disabled later if CET isn't enabled in
> +		 executable.  */
> +	      if (l == &GL(dl_rtld_map)
> +		  ||  l->l_real == &GL(dl_rtld_map)
> +		  || (program && l == m))
> +		continue;
> +#endif
> +
> +	      if (enable_ibt
> +		  && enable_ibt_type != CET_ALWAYS_ON
> +		  && !(l->l_cet & lc_ibt))
> +		{
> +		  /* Remember the first and last legacy objects.  */
> +		  if (!need_legacy_bitmap)
> +		    last_legacy = i;
> +		  first_legacy = i;
> +		  need_legacy_bitmap = true;
> +		}
> +
> +	      /* SHSTK is enabled only if it is enabled in executable as
> +		 well as all shared objects.  */
> +	      enable_shstk &= (enable_shstk_type == CET_ALWAYS_ON
> +			       || (l->l_cet & lc_shstk) != 0);
> +	    }
> +
> +	  if (need_legacy_bitmap)
> +	    {
> +	      if (GL(dl_x86_legacy_bitmap)[0])
> +		{
> +		  /* Change legacy bitmap to writable.  */
> +		  if (__mprotect ((void *) GL(dl_x86_legacy_bitmap)[0],
> +				  GL(dl_x86_legacy_bitmap)[1],
> +				  PROT_READ | PROT_WRITE) < 0)
> +		    {
> +mprotect_failure:
> +		      if (program)
> +			_dl_fatal_printf ("%s: mprotect legacy bitmap failed\n",
> +					  l->l_name);
> +		      else
> +			_dl_signal_error (EINVAL, l->l_name, "dlopen",
> +					  N_("mprotect legacy bitmap failed"));
> +		    }
> +		}
> +	      else
> +		{
> +		  /* Allocate legacy bitmap.  */
> +		  int res = dl_cet_allocate_legacy_bitmap
> +		    (GL(dl_x86_legacy_bitmap));
> +		  if (res != 0)
> +		    {
> +		      if (program)
> +			_dl_fatal_printf ("%s: legacy bitmap isn't available\n",
> +					  l->l_name);
> +		      else
> +			_dl_signal_error (EINVAL, l->l_name, "dlopen",
> +					  N_("legacy bitmap isn't available"));
> +		    }
> +		}
> +
> +	      /* Put legacy shared objects in legacy bitmap.  */
> +	      for (i = first_legacy; i <= last_legacy; i++)
> +		{
> +		  l = m->l_initfini[i];
> +
> +		  if (l->l_init_called || (l->l_cet & lc_ibt))
> +		    continue;
> +
> +#ifdef SHARED
> +		  if (l == &GL(dl_rtld_map)
> +		      ||  l->l_real == &GL(dl_rtld_map)
> +		      || (program && l == m))
> +		    continue;
> +#endif
> +
> +		  /* If IBT is enabled in executable and IBT isn't enabled
> +		     in this shard object, mark PT_LOAD segments with PF_X
> +		     in legacy code page bitmap.  */
> +		  res = dl_cet_mark_legacy_region (l);
> +		  if (res != 0)
> +		    {
> +		      if (program)
> +			_dl_fatal_printf ("%s: fail to mark legacy code region\n",

s/fail/failed/g

> +					  l->l_name);
> +		      else
> +			_dl_signal_error (-res, l->l_name, "dlopen",
> +					  N_("fail to mark legacy code region"));

s/fail/failed/g

> +		    }

OK.

> +		}
> +
> +	      /* Change legacy bitmap to read-only.  */
> +	      if (__mprotect ((void *) GL(dl_x86_legacy_bitmap)[0],
> +			      GL(dl_x86_legacy_bitmap)[1], PROT_READ) < 0)
> +		goto mprotect_failure;
> +	    }
> +	}
> +
> +      bool cet_feature_changed = false;
> +
> +      if (enable_ibt != ibt_enabled || enable_shstk != shstk_enabled)
> +	{
> +	  if (!program
> +	      && enable_shstk_type != CET_PERMISSIVE)
> +	    {
> +	      /* When SHSTK is enabled, we can't dlopening a shared
> +		 object without SHSTK.  */
> +	      if (enable_shstk != shstk_enabled)
> +		_dl_signal_error (EINVAL, l->l_name, "dlopen",
> +				  N_("shadow stack isn't enabled"));
> +	      return;
> +	    }
> +
> +	  /* Disable IBT and/or SHSTK if they are enabled by kernel, but
> +	     disabled in executable or shared objects.  */
> +	  unsigned int cet_feature = 0;
> +
> +	  /* Disable IBT only during program startup.  */
> +	  if (program && !enable_ibt)
> +	    cet_feature |= GNU_PROPERTY_X86_FEATURE_1_IBT;
> +	  if (!enable_shstk)
> +	    cet_feature |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
> +
> +	  int res = dl_cet_disable_cet (cet_feature);
> +	  if (res != 0)
> +	    {
> +	      if (program)
> +		_dl_fatal_printf ("%s: can't disable CET\n", program);
> +	      else
> +		_dl_signal_error (-res, l->l_name, "dlopen",
> +				  N_("can't disable CET"));
> +	    }
> +
> +	  /* Clear the disabled bits in dl_x86_feature_1.  */
> +	  GL(dl_x86_feature_1)[0] &= ~cet_feature;
> +
> +	  cet_feature_changed = true;
> +	}

OK.

> +
> +#ifdef SHARED
> +      if (program
> +	  && (!shstk_enabled
> +	      || enable_shstk_type != CET_PERMISSIVE)
> +	  && (ibt_enabled || shstk_enabled))
> +	{
> +	  /* Lock CET if IBT or SHSTK is enabled in executable.  Don't
> +	     lock CET if SHSTK is enabled permissively.  */
> +	  int res = dl_cet_lock_cet ();
> +	  if (res != 0)
> +	    _dl_fatal_printf ("%s: can't lock CET\n", program);
> +
> +	  cet_feature_changed = true;
> +	}
> +#endif
> +
> +      if (cet_feature_changed)
> +	{
> +	  unsigned int feature_1 = 0;
> +	  if (enable_ibt)
> +	    feature_1 |= GNU_PROPERTY_X86_FEATURE_1_IBT;
> +	  if (enable_shstk)
> +	    feature_1 |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
> +	  struct pthread *self = THREAD_SELF;
> +	  THREAD_SETMEM (self, header.feature_1, feature_1);
> +	}
> +    }
> +}
> +
> +void
> +_dl_cet_open_check (struct link_map *l)
> +{
> +  dl_cet_check (l, NULL);
> +}
> +
> +#ifdef SHARED
> +
> +# ifndef LINKAGE
> +#  define LINKAGE
> +# endif
> +
> +LINKAGE
> +void
> +_dl_cet_check (struct link_map *main_map, const char *program)
> +{
> +  dl_cet_check (main_map, program);
> +}
> +#endif /* SHARED */
> diff --git a/sysdeps/x86/dl-procruntime.c b/sysdeps/x86/dl-procruntime.c
> new file mode 100644
> index 0000000000..eddbde6a31
> --- /dev/null
> +++ b/sysdeps/x86/dl-procruntime.c
> @@ -0,0 +1,68 @@
> +/* Data for processor runtime information.  x86 version.
> +   Copyright (C) 2018 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* This information must be kept in sync with the _DL_HWCAP_COUNT,
> +   HWCAP_PLATFORMS_START and HWCAP_PLATFORMS_COUNT definitions in
> +   dl-hwcap.h.
> +
> +   If anything should be added here check whether the size of each string
> +   is still ok with the given array size.
> +
> +   All the #ifdefs in the definitions are quite irritating but
> +   necessary if we want to avoid duplicating the information.  There
> +   are three different modes:
> +
> +   - PROCINFO_DECL is defined.  This means we are only interested in
> +     declarations.
> +
> +   - PROCINFO_DECL is not defined:
> +
> +     + if SHARED is defined the file is included in an array
> +       initializer.  The .element = { ... } syntax is needed.
> +
> +     + if SHARED is not defined a normal array initialization is
> +       needed.
> +  */
> +
> +#ifndef PROCINFO_CLASS
> +# define PROCINFO_CLASS
> +#endif
> +
> +#if !IS_IN (ldconfig)
> +# if !defined PROCINFO_DECL && defined SHARED
> +  ._dl_x86_feature_1
> +# else
> +PROCINFO_CLASS unsigned int _dl_x86_feature_1[2]
> +# endif
> +# if !defined SHARED || defined PROCINFO_DECL
> +;
> +# else
> +,
> +# endif
> +
> +# if !defined PROCINFO_DECL && defined SHARED
> +  ._dl_x86_legacy_bitmap
> +# else
> +PROCINFO_CLASS unsigned long _dl_x86_legacy_bitmap[2]
> +# endif
> +# if !defined SHARED || defined PROCINFO_DECL
> +;
> +# else
> +,
> +# endif
> +#endif

OK.

> diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h
> new file mode 100644
> index 0000000000..2709fe852d
> --- /dev/null
> +++ b/sysdeps/x86/dl-prop.h
> @@ -0,0 +1,153 @@
> +/* Support for GNU properties.  x86 version.
> +   Copyright (C) 2018 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef _DL_PROP_H
> +#define _DL_PROP_H
> +
> +#include <not-cancel.h>
> +
> +extern void _dl_cet_check (struct link_map *, const char *)
> +    attribute_hidden;
> +extern void _dl_cet_open_check (struct link_map *)
> +    attribute_hidden;
> +
> +static inline void __attribute__ ((always_inline))
> +_rtld_main_check (struct link_map *m, const char *program)
> +{
> +#ifdef __CET__
> +  _dl_cet_check (m, program);
> +#endif
> +}

OK.

> +
> +static inline void __attribute__ ((always_inline))
> +_dl_open_check (struct link_map *m)
> +{
> +#ifdef __CET__
> +  _dl_cet_open_check (m);
> +#endif
> +}

OK.

> +
> +static inline void __attribute__ ((unused))
> +_dl_process_cet_property_note (struct link_map *l,
> +			      const ElfW(Nhdr) *note,
> +			      const ElfW(Addr) size,
> +			      const ElfW(Addr) align)
> +{
> +#ifdef __CET__
> +  /* The NT_GNU_PROPERTY_TYPE_0 note must be aliged to 4 bytes in
> +     32-bit objects and to 8 bytes in 64-bit objects.  Skip notes
> +     with incorrect alignment.  */
> +  if (align != (__ELF_NATIVE_CLASS / 8))
> +    return;
> +
> +  const ElfW(Addr) start = (ElfW(Addr)) note;
> +
> +  while ((ElfW(Addr)) (note + 1) - start < size)

OK. For the next arch that needs property handling we should genarlize
some of these things in the future (not needed for 2.28).

> +    {
> +      /* Find the NT_GNU_PROPERTY_TYPE_0 note.  */
> +      if (note->n_namesz == 4
> +	  && note->n_type == NT_GNU_PROPERTY_TYPE_0
> +	  && memcmp (note + 1, "GNU", 4) == 0)

OK.

> +	{
> +	  /* Check for invalid property.  */
> +	  if (note->n_descsz < 8
> +	      || (note->n_descsz % sizeof (ElfW(Addr))) != 0)
> +	    break;

OK.

> +
> +	  /* Start and end of property array.  */
> +	  unsigned char *ptr = (unsigned char *) (note + 1) + 4;
> +	  unsigned char *ptr_end = ptr + note->n_descsz;
> +
> +	  while (1)
> +	    {
> +	      unsigned int type = *(unsigned int *) ptr;
> +	      unsigned int datasz = *(unsigned int *) (ptr + 4);
> +
> +	      ptr += 8;
> +	      if ((ptr + datasz) > ptr_end)
> +		break;
> +
> +	      if (type == GNU_PROPERTY_X86_FEATURE_1_AND
> +		  && datasz == 4)

OK.

> +		{
> +		  unsigned int feature_1 = *(unsigned int *) ptr;
> +		  if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT))
> +		    l->l_cet |= lc_ibt;
> +		  if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
> +		    l->l_cet |= lc_shstk;
> +		  break;
> +		}
> +	    }
> +	}
> +
> +      /* NB: Note sections like .note.ABI-tag and .note.gnu.build-id are
> +	 aligned to 4 bytes in 64-bit ELF objects.  */
> +      note = ((const void *) note
> +	      + ELF_NOTE_NEXT_OFFSET (note->n_namesz, note->n_descsz,
> +				      align));
> +    }
> +#endif
> +}

OK.

> +
> +#ifdef FILEBUF_SIZE
> +static inline int __attribute__ ((unused))
> +_dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph,
> +		     int fd, struct filebuf *fbp)
> +{
> +# ifdef __CET__
> +  const ElfW(Nhdr) *note;
> +  ElfW(Nhdr) *note_malloced = NULL;
> +  ElfW(Addr) size = ph->p_filesz;
> +
> +  if (ph->p_offset + size <= (size_t) fbp->len)
> +    note = (const void *) (fbp->buf + ph->p_offset);
> +  else
> +    {
> +      if (size < __MAX_ALLOCA_CUTOFF)
> +	note = alloca (size);
> +      else
> +	{
> +	  note_malloced = malloc (size);
> +	  note = note_malloced;
> +	}
> +      __lseek (fd, ph->p_offset, SEEK_SET);
> +      if (__read_nocancel (fd, (void *) note, size) != size)
> +	{
> +	  if (note_malloced)
> +	    free (note_malloced);
> +	  return -1;
> +	}
> +    }
> +
> +  _dl_process_cet_property_note (l, note, size, ph->p_align);
> +  if (note_malloced)
> +    free (note_malloced);
> +# endif
> +  return 0;
> +}
> +#endif

OK.

> +
> +static inline int __attribute__ ((unused))
> +_rtld_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph)
> +{
> +  const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_addr);
> +  _dl_process_cet_property_note (l, note, ph->p_memsz, ph->p_align);
> +  return 0;
> +}

OK.

> +
> +#endif /* _DL_PROP_H */
> diff --git a/sysdeps/x86/dl-tunables.list b/sysdeps/x86/dl-tunables.list
> index 7c3236a68f..73886b1352 100644
> --- a/sysdeps/x86/dl-tunables.list
> +++ b/sysdeps/x86/dl-tunables.list
> @@ -21,6 +21,12 @@ glibc {
>      hwcaps {
>        type: STRING
>      }
> +    x86_ibt {
> +      type: STRING
> +    }
> +    x86_shstk {
> +      type: STRING
> +    }

OK.

>      x86_non_temporal_threshold {
>        type: SIZE_T
>      }
> diff --git a/sysdeps/x86/libc-start.h b/sysdeps/x86/libc-start.h
> new file mode 100644
> index 0000000000..6f44262bf4
> --- /dev/null
> +++ b/sysdeps/x86/libc-start.h
> @@ -0,0 +1,25 @@
> +/* X86 definitions for libc main startup.
> +   Copyright (C) 2018 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef SHARED
> +# define ARCH_SETUP_IREL() apply_irel ()
> +# define ARCH_APPLY_IREL()
> +# ifndef ARCH_SETUP_TLS
> +#  define ARCH_SETUP_TLS() __libc_setup_tls ()
> +# endif
> +#endif /* !SHARED */

OK.

> diff --git a/sysdeps/x86/link_map.h b/sysdeps/x86/link_map.h
> new file mode 100644
> index 0000000000..ef1206a9d2
> --- /dev/null
> +++ b/sysdeps/x86/link_map.h
> @@ -0,0 +1,26 @@
> +/* Additional fields in struct link_map.  Linux/x86 version.
> +   Copyright (C) 2018 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* If this object is enabled with CET.  */
> +enum
> +  {
> +    lc_none = 0,			 /* Not enabled with CET.  */
> +    lc_ibt = 1 << 0,			 /* Enabled with IBT.  */
> +    lc_shstk = 1 << 1,			 /* Enabled with STSHK.  */
> +    lc_ibt_and_shstk = lc_ibt | lc_shstk /* Enabled with both.  */
> +  } l_cet:2;

OK.

> diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h
> index afcb7cfd76..9843d9dff7 100644
> --- a/sysdeps/x86/sysdep.h
> +++ b/sysdeps/x86/sysdep.h
> @@ -25,6 +25,13 @@
>  
>  /* Syntactic details of assembler.  */
>  
> +#ifdef _CET_ENDBR
> +# define _CET_NOTRACK notrack
> +#else
> +# define _CET_ENDBR
> +# define _CET_NOTRACK
> +#endif

OK.

> +
>  /* ELF uses byte-counts for .align, most others use log2 of count of bytes.  */
>  #define ALIGNARG(log2) 1<<log2
>  #define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
> @@ -36,6 +43,7 @@
>    .align ALIGNARG(4);							      \
>    C_LABEL(name)								      \
>    cfi_startproc;							      \
> +  _CET_ENDBR;	

OK.

							      \
>    CALL_MCOUNT
>  
>  #undef	END
> diff --git a/sysdeps/x86_64/dl-trampoline.h b/sysdeps/x86_64/dl-trampoline.h
> index 298cfb3d99..a28b1e73a4 100644
> --- a/sysdeps/x86_64/dl-trampoline.h
> +++ b/sysdeps/x86_64/dl-trampoline.h
> @@ -64,6 +64,7 @@
>  	cfi_startproc
>  _dl_runtime_resolve:
>  	cfi_adjust_cfa_offset(16) # Incorporate PLT
> +	_CET_ENDBR
>  # if DL_RUNTIME_RESOLVE_REALIGN_STACK
>  #  if LOCAL_STORAGE_AREA != 8
>  #   error LOCAL_STORAGE_AREA must be 8
> @@ -168,6 +169,7 @@ _dl_runtime_resolve:
>  _dl_runtime_profile:
>  	cfi_startproc
>  	cfi_adjust_cfa_offset(16) # Incorporate PLT
> +	_CET_ENDBR
>  	/* The La_x86_64_regs data structure pointed to by the
>  	   fourth paramater must be VEC_SIZE-byte aligned.  This must
>  	   be explicitly enforced.  We have the set up a dynamically
> -- 2.17.1

OK.

-- 
Cheers,
Carlos.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]