Commit Graph

2 Commits

Author SHA1 Message Date
H.J. Lu 48580982ef x86: Support Intel Shadow Stack with SHSTK property
To support Intel Shadow Stack (SHSTK) in Intel Control-flow Enforcement
Technology (CET) instructions:

https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf

 #define GNU_PROPERTY_X86_FEATURE_1_SHSTK (1U << 1)

is added to GNU program properties 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.

GNU_PROPERTY_X86_FEATURE_1_SHSTK is set on output only if it is set on all
relocatable inputs.

bfd/

	* elf32-i386.c (elf_i386_merge_gnu_properties): If info->shstk
	is set, turn on GNU_PROPERTY_X86_FEATURE_1_SHSTK.
	(elf_i386_link_setup_gnu_properties): If info->shstk is set,
	turn on GNU_PROPERTY_X86_FEATURE_1_IBT.
	* elf64-x86-64.c (elf_x86_64_merge_gnu_properties): If
	info->shstk is set, turn on GNU_PROPERTY_X86_FEATURE_1_SHSTK.
	(elf_x86_64_link_setup_gnu_properties): If info->shstk is set,
	turn on GNU_PROPERTY_X86_FEATURE_1_IBT.

binutils/

	* readelf.c (decode_x86_feature): Decode
	GNU_PROPERTY_X86_FEATURE_1_SHSTK.
	* testsuite/binutils-all/i386/shstk.d: New file.
	* testsuite/binutils-all/i386/shstk.s: Likewise.
	* testsuite/binutils-all/x86-64/shstk-x32.d: Likewise.
	* testsuite/binutils-all/x86-64/shstk.d: Likewise.
	* testsuite/binutils-all/x86-64/shstk.s: Likewise.

include/

	* bfdlink.h (bfd_link_info): Add shstk.
	* elf/common.h (GNU_PROPERTY_X86_FEATURE_1_SHSTK): New.

ld/

	* NEWS: Mention -z shstk and GNU_PROPERTY_X86_FEATURE_1_SHSTK.
	* emulparams/cet.sh (PARSE_AND_LIST_OPTIONS_CET): Add "-z shstk".
	(PARSE_AND_LIST_ARGS_CASE_Z_CET): Support "-z shstk".
	* ld.texinfo: Document -z shstk.
	* testsuite/ld-i386/i386.exp: Run SHSTK tests.
	* testsuite/ld-x86-64/x86-64.exp: Likewise.
	* testsuite/ld-i386/property-x86-shstk.s: New file.
	* testsuite/ld-i386/property-x86-shstk1a.d: Likewise.
	* testsuite/ld-i386/property-x86-shstk1b.d: Likewise.
	* testsuite/ld-i386/property-x86-shstk2.d: Likewise.
	* testsuite/ld-i386/property-x86-shstk3a.d: Likewise.
	* testsuite/ld-i386/property-x86-shstk3b.d: Likewise.
	* testsuite/ld-i386/property-x86-shstk4.d: Likewise.
	* testsuite/ld-i386/property-x86-shstk5.d: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk.s: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk1a-x32.d: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk1a.d: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk1b-x32.d: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk1b.d: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk2-x32.d: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk2.d: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk3a-x32.d: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk3a.d: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk3b-x32.d: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk3b.d: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk4-x32.d: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk4.d: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk5-x32.d: Likewise.
	* testsuite/ld-x86-64/property-x86-shstk5.d: Likewise.
2017-06-22 05:50:31 -07:00
H.J. Lu ee2fdd6f36 x86: Support Intel IBT with IBT property and IBT-enable PLT
To support IBT in Intel Control-flow Enforcement Technology (CET)
instructions:

https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf

 #define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002

 #define GNU_PROPERTY_X86_FEATURE_1_IBT (1U << 0)

are added to GNU program properties to indicate that all executable
sections are compatible with IBT when ENDBR instruction starts each
valid target where an indirect branch instruction can land.

GNU_PROPERTY_X86_FEATURE_1_IBT is set on output only if it is set on
all relocatable inputs.

The followings changes are made to the Procedure Linkage Table (PLT):

1. For 64-bit x86-64,  PLT is changed to

PLT0:  push       GOT[1]
       bnd jmp    *GOT[2]
       nop
...
PLTn:  endbr64
       push       namen_reloc_index
       bnd jmp    PLT0

together with the second PLT section:

PLTn:  endbr64
       bnd jmp   *GOT[namen_index]
       nop

BND prefix is also added so that IBT-enabled PLT is compatible with MPX.

2. For 32-bit x86-64 (x32) and i386,  PLT is changed to

PLT0:  push       GOT[1]
       jmp        *GOT[2]
       nop
...
PLTn:  endbr64                                 # endbr32 for i386.
       push       namen_reloc_index
       jmp        PLT0

together with the second PLT section:

PLTn:  endbr64                                 # endbr32 for i386.
       jmp       *GOT[namen_index]
       nop

BND prefix isn't used since MPX isn't supported on x32 and BND registers
aren't used in parameter passing on i386.

GOT is an array of addresses.  Initially, GOT[namen_index] is filled
with the address of the ENDBR instruction of the corresponding entry
in the first PLT section.  The function, namen, is called via the
ENDBR instruction in the second PLT entry.  GOT[namen_index] is updated
to the actual address of the function, namen, at run-time.

2 linker command line options are added:

1. -z ibtplt: Generate IBT-enabled PLT.
2. -z ibt: Generate GNU_PROPERTY_X86_FEATURE_1_IBT in GNU program
properties as well as IBT-enabled PLT.

bfd/

	* elf32-i386.c (elf_i386_lazy_ibt_plt0_entry): New.
	(elf_i386_lazy_ibt_plt_entry): Likewise.
	(elf_i386_pic_lazy_ibt_plt0_entry): Likewise.
	(elf_i386_non_lazy_ibt_plt_entry): Likewise.
	(elf_i386_pic_non_lazy_ibt_plt_entry): Likewise.
	(elf_i386_eh_frame_lazy_ibt_plt): Likewise.
	(elf_i386_lazy_plt_layout): Likewise.
	(elf_i386_non_lazy_plt_layout): Likewise.
	(elf_i386_link_hash_entry): Add plt_second.
	(elf_i386_link_hash_table): Add plt_second and
	plt_second_eh_frame.
	(elf_i386_allocate_dynrelocs): Use the second PLT if needed.
	(elf_i386_size_dynamic_sections): Use .plt.got unwind info for
	the second PLT.  Check the second PLT.
	(elf_i386_relocate_section): Use the second PLT to resolve
	PLT reference if needed.
	(elf_i386_finish_dynamic_symbol): Fill and use the second PLT if
	needed.
	(elf_i386_finish_dynamic_sections): Set sh_entsize on the
	second PLT.  Generate unwind info for the second PLT.
	(elf_i386_plt_type): Add plt_second.
	(elf_i386_get_synthetic_symtab): Support the second PLT.
	(elf_i386_parse_gnu_properties): Support
	GNU_PROPERTY_X86_FEATURE_1_AND.
	(elf_i386_merge_gnu_properties): Support
	GNU_PROPERTY_X86_FEATURE_1_AND.  If info->ibt is set, turn
	on GNU_PROPERTY_X86_FEATURE_1_IBT
	(elf_i386_link_setup_gnu_properties): If info->ibt is set,
	turn on GNU_PROPERTY_X86_FEATURE_1_IBT.  Use IBT-enabled PLT
	for info->ibtplt, info->ibt or GNU_PROPERTY_X86_FEATURE_1_IBT
	is set on all relocatable inputs.
	* elf64-x86-64.c (elf_x86_64_lazy_ibt_plt_entry): New.
	(elf_x32_lazy_ibt_plt_entry): Likewise.
	(elf_x86_64_non_lazy_ibt_plt_entry): Likewise.
	(elf_x32_non_lazy_ibt_plt_entry): Likewise.
	(elf_x86_64_eh_frame_lazy_ibt_plt): Likewise.
	(elf_x32_eh_frame_lazy_ibt_plt): Likewise.
	(elf_x86_64_lazy_ibt_plt): Likewise.
	(elf_x32_lazy_ibt_plt): Likewise.
	(elf_x86_64_non_lazy_ibt_plt): Likewise.
	(elf_x32_non_lazy_ibt_plt): Likewise.
	(elf_x86_64_get_synthetic_symtab): Support the second PLT.
	(elf_x86_64_parse_gnu_properties): Support
	GNU_PROPERTY_X86_FEATURE_1_AND.
	(elf_x86_64_merge_gnu_properties): Support
	GNU_PROPERTY_X86_FEATURE_1_AND.  If info->ibt is set, turn
	on GNU_PROPERTY_X86_FEATURE_1_IBT
	(elf_x86_64_link_setup_gnu_properties): If info->ibt is set,
	turn on GNU_PROPERTY_X86_FEATURE_1_IBT.  Use IBT-enabled PLT
	for info->ibtplt, info->ibt or GNU_PROPERTY_X86_FEATURE_1_IBT
	is set on all relocatable inputs.

binutils/

	* readelf.c (decode_x86_feature): New.
	(print_gnu_property_note): Call decode_x86_feature on
	GNU_PROPERTY_X86_FEATURE_1_AND.
	* testsuite/binutils-all/i386/empty.d: New file.
	* testsuite/binutils-all/i386/empty.s: Likewise.
	* testsuite/binutils-all/i386/ibt.d: Likewise.
	* testsuite/binutils-all/i386/ibt.s: Likewise.
	* testsuite/binutils-all/x86-64/empty-x32.d: Likewise.
	* testsuite/binutils-all/x86-64/empty.d: Likewise.
	* testsuite/binutils-all/x86-64/empty.s: Likewise.
	* testsuite/binutils-all/x86-64/ibt-x32.d: Likewise.
	* testsuite/binutils-all/x86-64/ibt.d: Likewise.
	* testsuite/binutils-all/x86-64/ibt.s: Likewise.

include/

	* bfdlink.h (bfd_link_info): Add ibtplt and ibt.
	* elf/common.h (GNU_PROPERTY_X86_FEATURE_1_AND): New.
	(GNU_PROPERTY_X86_FEATURE_1_IBT): Likewise.

ld/

	* Makefile.am (ELF_X86_DEPS): Add $(srcdir)/emulparams/cet.sh.
	* Makefile.in: Regenerated.
	* NEWS: Mention GNU_PROPERTY_X86_FEATURE_1_IBT, -z ibtplt
	and -z ibt.
	* emulparams/cet.sh: New file.
	* testsuite/ld-i386/ibt-plt-1.d: Likewise.
	* testsuite/ld-i386/ibt-plt-1.s: Likewise.
	* testsuite/ld-i386/ibt-plt-2.s: Likewise.
	* testsuite/ld-i386/ibt-plt-2a.d: Likewise.
	* testsuite/ld-i386/ibt-plt-2b.d: Likewise.
	* testsuite/ld-i386/ibt-plt-2c.d: Likewise.
	* testsuite/ld-i386/ibt-plt-2d.d: Likewise.
	* testsuite/ld-i386/ibt-plt-3.s: Likewise.
	* testsuite/ld-i386/ibt-plt-3a.d: Likewise.
	* testsuite/ld-i386/ibt-plt-3b.d: Likewise.
	* testsuite/ld-i386/ibt-plt-3c.d: Likewise.
	* testsuite/ld-i386/ibt-plt-3d.d: Likewise.
	* testsuite/ld-i386/plt-main-ibt.dd: Likewise.
	* testsuite/ld-i386/plt-pie-ibt.dd: Likewise.
	* testsuite/ld-i386/property-x86-empty.s: Likewise.
	* testsuite/ld-i386/property-x86-ibt.s: Likewise.
	* testsuite/ld-i386/property-x86-ibt1a.d: Likewise.
	* testsuite/ld-i386/property-x86-ibt1b.d: Likewise.
	* testsuite/ld-i386/property-x86-ibt2.d: Likewise.
	* testsuite/ld-i386/property-x86-ibt3a.d: Likewise.
	* testsuite/ld-i386/property-x86-ibt3b.d: Likewise.
	* testsuite/ld-i386/property-x86-ibt4.d: Likewise.
	* testsuite/ld-i386/property-x86-ibt5.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-1-x32.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-1.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-1.s: Likewise.
	* testsuite/ld-x86-64/ibt-plt-2.s: Likewise.
	* testsuite/ld-x86-64/ibt-plt-2a-x32.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-2a.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-2b-x32.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-2b.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-2c-x32.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-2c.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-2d-x32.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-2d.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-3.s: Likewise.
	* testsuite/ld-x86-64/ibt-plt-3a-x32.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-3a.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-3b-x32.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-3b.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-3c-x32.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-3c.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-3d-x32.d: Likewise.
	* testsuite/ld-x86-64/ibt-plt-3d.d: Likewise.
	* testsuite/ld-x86-64/plt-main-ibt-now.rd: Likewise.
	* testsuite/ld-x86-64/plt-main-ibt-x32.dd: Likewise.
	* testsuite/ld-x86-64/plt-main-ibt.dd: Likewise.
	* testsuite/ld-x86-64/property-x86-empty.s: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt.s: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt1a-x32.d: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt1a.d: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt1b-x32.d: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt1b.d: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt2-x32.d: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt2.d: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt3a-x32.d: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt3a.d: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt3b-x32.d: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt3b.d: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt4-x32.d: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt4.d: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt5-x32.d: Likewise.
	* testsuite/ld-x86-64/property-x86-ibt5.d: Likewise.
	* emulparams/elf32_x86_64.sh: Source emulparams/cet.sh.
	(TINY_READONLY_SECTION): Add .plt.sec.
	* emulparams/elf_i386.sh: Likewise.
	* emulparams/elf_x86_64.sh: Source emulparams/cet.sh.
	* ld.texinfo: Document -z ibtplt and -z ibt.
	* testsuite/ld-i386/i386.exp: Run IBT and IBT PLT tests.
	* testsuite/ld-x86-64/x86-64.exp: Likewise.
	* testsuite/ld-x86-64/pr21481b.S (check): Updated for x32.
2017-06-22 05:44:53 -07:00