[BFD,LD,AArch64,3/4] Add --bti to enable BTI and select BTI enabled PLTs but also warn for missing NOTE sections.

Message ID 28fed67e-7286-0526-3974-7312b0418405@arm.com
State New
Headers show
Series
  • Add support for AArch64 BTI and PAC in the linker
Related show

Commit Message

Sudakshina Das March 6, 2019, 10:36 a.m.
Hi

On 06/03/2019 10:34, Sudakshina Das wrote:
> Hi

> 

> On 06/03/2019 10:30, Sudakshina Das wrote:

>> Hi

>>

>> On 06/03/2019 10:26, Sudakshina Das wrote:

>>> Hi

>>>

>>> This patch series is aimed at giving support for the new Armv8.3-A 

>>> Pointer Authentication and Armv8.5-A Branch Target Identification 

>>> feature in the linker.

>>>

>>> In order to support these, we propose to make the following changes:

>>> 1) We have defined .note.gnu.property for AArch64.

>>> 2) We have defined a new Program Property type

>>> GNU_PROPERTY_AARCH64_FEATURE_1_AND and used 2 bits to represent

>>> BTI and PAC respectively.

>>>    - GNU_PROPERTY_AARCH64_FEATURE_1_BTI

>>>    - GNU_PROPERTY_AARCH64_FEATURE_1_PAC (We have only reserved this bit

>>>      for now.)

>>> 3) We also need custom PLTs when these features are turned on and thus

>>> we have defined the following processor-specific dynamic array tags:

>>>    - DT_AARCH64_BTI_PLT

>>>    - DT_AARCH64_PAC_PLT

>>> Details of these can be found in the new AArch64 ELF documentation:

>>> https://developer.arm.com/docs/ihi0056/latest/elf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4 

>>>

>>>

>>> Command line options:

>>> We introduce a new set of command line options for the linker in 

>>> order to support the correct PLTs

>>> 1) --pac-plt : In the presence of this option, the linker uses a PAC 

>>> enabled PLT. It also uses the dynamic tag DT_AARCH64_PAC_PLT to 

>>> reflect the same. Other tools like Objdump can use this to determine 

>>> the size of the PLTs.

>>> 2) --bti: In the presence of this option, the linker enables BTI with 

>>> the GNU_PROPERTY_AARCH64_FEATURE_1_BTI feature and also uses a BTI 

>>> enabled PLT. It also uses the dynamic tag DT_AARCH64_BTI_PLT to 

>>> reflect the choice of the PLTs. Other tools like Objdump can use this 

>>> to determine the size of the PLTs. Using this option can give a 

>>> warning if not all input objects are marked with 

>>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI.

>>> 3)--bti-nowarn - Same as above but does not emit any warnings.

>>>

>>> In terms of the PLTs, in the presence of both --pac-plt and 

>>> --bti/--bti-nowarn, the linker chooses the PLTs protected with both 

>>> BTI and PAC and uses both DT_AARCH64_PAC_PLT and DT_AARCH64_BTI_PLT.

>>>

>>> Interaction between Command line arguments and GNU NOTE section

>>> 1) For PAC, in the presence of --pac-plt along with BIND_NOW, the 

>>> linker can choose to ignore the pac-plt directive and use smaller 

>>> PLTs without compromising on security,

>>> 2) For BTI, the linker must also check for the 

>>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI in its input. If all inputs have 

>>> GNU_PROPERTY_AARCH64_FEATURE_1_BTI, the final output will also be 

>>> marked as such. The PLT should also be protected with a BTI PLT in 

>>> this case. Thus even if there is no linker option to use BTI PLT, the 

>>> linker

>>> should be able to use them depending on the NOTE section. The user 

>>> can use the linker option --bti, to make sure that their intention of 

>>> having all input objects (and hence the output) marked with BTI is 

>>> not disrupted by any stray objects as this option will warn about it.

>>>

>>>

>>> The following patches implement these changes as follows:

>>> [1/4] Add support for GNU PROPERTIES in AArch64 for BTI and PAC:

>>> [2/4] Add --bti-nowarn to enable BTI without warning and to select 

>>> BTI enabled PLTs

>>> [3/4] Add --bti to enable BTI and select BTI enabled PLTs but also 

>>> warn for missing NOTE sections.

>>> [4/4] Add --pac-plt to enable PLTs protected with PAC.

>>>

>>> This is my first time making such intrusive changes to the linker. 

>>> Please be kind :P

>>>

>>> Thanks

>>> Sudi

>>

>> This is part of the patch series to add support for BTI and

>> PAC in AArch64 linker.

>>

>> This patch implements the following:

>> 1) This extends in the gnu property support in the linker for

>> AArch64 by defining backend hooks for elf_backend_setup_gnu_properties,

>> elf_backend_merge_gnu_properties and elf_backend_parse_gnu_properties.

>> 2) It defines AArch64 specific GNU property

>> GNU_PROPERTY_AARCH64_FEATURE_1_AND and 2 bit for BTI and PAC in it.

>> 3) It also adds support in readelf.c to read and print these new

>> GNU properties in AArch64.

>> All these are made according to the new AArch64 ELF ABI

>> https://developer.arm.com/docs/ihi0056/latest/elf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4 

>>

>>

>> Build and regression tests all pass on aarch64-none-linux-gnu and

>> new tests are added.

>>

>> Is this ok for trunk?

>>

>> Thanks

>> Sudi

>>

>> *** bfd/ChangeLog ***

>>

>> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

>>

>>      * elf-properties.c (_bfd_elf_link_setup_gnu_properties): Exclude

>>      linker created inputs from merge.

>>      * elfnn-aarch64.c (struct elf_aarch64_obj_tdata): Add field for

>>      GNU_PROPERTY_AARCH64_FEATURE_1_AND properties.

>>      (elfNN_aarch64_link_setup_gnu_properties): New.

>>      (elfNN_aarch64_merge_gnu_properties): New.

>>      (elf_backend_setup_gnu_properties): Define for AArch64.

>>      (elf_backend_merge_gnu_properties): Likewise.

>>      * elfxx-aarch64.c (_bfd_aarch64_elf_link_setup_gnu_properties): 

>> Define.

>>      (_bfd_aarch64_elf_parse_gnu_properties): Define.

>>      (_bfd_aarch64_elf_merge_gnu_properties): Define.

>>      * elfxx-aarch64.h (_bfd_aarch64_elf_link_setup_gnu_properties): 

>> Declare.

>>      (_bfd_aarch64_elf_parse_gnu_properties): Declare.

>>      (_bfd_aarch64_elf_merge_gnu_properties): Declare.

>>      (elf_backend_parse_gnu_properties): Define for AArch64.

>>

>> *** binutils/ChangeLog ***

>>

>> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

>>

>>      * readelf.c (decode_aarch64_feature_1_and): New.

>>      (print_gnu_property_note): Add case for AArch64 gnu notes.

>>

>> *** include/ChangeLog ***

>>

>> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

>>

>>      * elf/common.h (GNU_PROPERTY_AARCH64_FEATURE_1_AND): New.

>>      (GNU_PROPERTY_AARCH64_FEATURE_1_BTI): New.

>>      (GNU_PROPERTY_AARCH64_FEATURE_1_PAC): New.

>>

>> *** ld/ChangeLog ***

>>

>> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

>>

>>      * NEWS: Document GNU_PROPERTY_AARCH64_FEATURE_1_BTI and

>>      GNU_PROPERTY_AARCH64_FEATURE_1_PAC.

>>      * testsuite/ld-aarch64/aarch64-elf.exp: Add run commands for new 

>> tests.

>>      * testsuite/ld-aarch64/property-bti-pac1.d: New test.

>>      * testsuite/ld-aarch64/property-bti-pac1.s: New test.

>>      * testsuite/ld-aarch64/property-bti-pac2.d: New test.

>>      * testsuite/ld-aarch64/property-bti-pac2.s: New test.

>>      * testsuite/ld-aarch64/property-bti-pac3.d: New test.

> 

> This is part of the patch series to add support for BTI and

> PAC in AArch64 linker.

> 

> 1) This patch adds a new ld command line option: --bti-nowarn.

> In the presence of this option, the linker enables BTI with the

> GNU_PROPERTY_AARCH64_FEATURE_1_BTI feature. This gives no warning

> in case of missing gnu notes for BTI in inputs.

> 2) It also defines a new set of BTI enabled PLTs. These are used either

> when all the inputs are marked with GNU_PROPERTY_AARCH64_FEATURE_1_BTI

> or when the new --bti-nowarn option is used. This required adding new

> fields in elf_aarch64_link_hash_table so that we could make the PLT

> related information more generic.

> 3) It also defines a dynamic tag DT_AARCH64_BTI_PLT. The linker uses

> this whenever it picks BTI enabled PLTs.

> All these are made according to the new AArch64 ELF ABI

> https://developer.arm.com/docs/ihi0056/latest/elf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4 

> 

> 

> Build and regression tests all pass on aarch64-none-linux-gnu and

> new tests are added.

> 

> Is this ok for trunk?

> 

> Thanks

> Sudi

> 

> *** bfd/ChangeLog ***

> 

> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

>          Szabolcs Nagy  <szabolcs.nagy@arm.com>

> 

>      * bfd-in.h (aarch64_plt_type, aarch64_enable_bti_type): New.

>      (aarch64_bti_pac_info): New.

>      (bfd_elf64_aarch64_set_options): Add aarch64_bti_pac_info argument.

>      (bfd_elf32_aarch64_set_options): Likewise.

>      * bfd-in2.h: Regenerate

>      * elfnn-aarch64.c (PLT_BTI_ENTRY_SIZE): New.

>      (PLT_BTI_SMALL_ENTRY_SIZE, PLT_BTI_TLSDESC_ENTRY_SIZE): New.

>      (elfNN_aarch64_small_plt0_bti_entry): New.

>      (elfNN_aarch64_small_plt_bti_entry): New.

>      (elfNN_aarch64_tlsdesc_small_plt_bti_entry): New.

>      (elf_aarch64_obj_tdata): Add no_enable_bti_warn and plt_type fields.

>      (elf_aarch64_link_hash_table): Add plt0_entry, plt_entry and

>      tlsdesc_plt_entry_size fields.

>      (elfNN_aarch64_link_hash_table_create): Initialise the new fields.

>      (setup_plt_values): New helper function.

>      (bfd_elfNN_aarch64_set_options): Use new bp_info to set plt sizes and

>      bti enable type.

>      (elfNN_aarch64_allocate_dynrelocs): Use new size members instead of

>      fixed macros.

>      (elfNN_aarch64_size_dynamic_sections): Likewise and add checks.

>      (elfNN_aarch64_create_small_pltn_entry): Use new generic pointers

>      to plt stubs instead of fixed ones and update filling them according

>      to the need for bti.

>      (elfNN_aarch64_init_small_plt0_entry): Likewise.

>      (elfNN_aarch64_finish_dynamic_sections): Likewise.

>      (get_plt_type, elfNN_aarch64_get_synthetic_symtab): New.

>      (elfNN_aarch64_plt_sym_val): Update size accordingly.

>      (elfNN_aarch64_link_setup_gnu_properties): Set up plts if BTI GNU NOTE

>      is set.

>      (bfd_elfNN_get_synthetic_symtab): Define.

> 

> *** binutils/ChangeLog ***

> 

> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

>          Szabolcs Nagy  <szabolcs.nagy@arm.com>

> 

>      * readelf.c (get_aarch64_dynamic_type): New.

>      (get_dynamic_type): Use above for EM_AARCH64.

>      (dynamic_section_aarch64_val): New.

>      (process_dynamic_section): Use above for EM_AARCH64.

> 

> *** include/ChangeLog ***

> 

> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

>          Szabolcs Nagy  <szabolcs.nagy@arm.com>

> 

>      * elf/aarch64.h (DT_AARCH64_BTI_PLT): New.

> 

> *** ld/ChangeLog ***

> 

> 2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

>          Szabolcs Nagy  <szabolcs.nagy@arm.com>

> 

>      * NEWS: Document --bti-nowarn.

>      * emultempl/aarch64elf.em (plt_type, bti_type, OPTION_BTI_NOWARN): 

> New.

>      (PARSE_AND_LIST_SHORTOPTS, PARSE_AND_LIST_OPTIONS): Add bti-nowarn.

>      (PARSE_AND_LIST_ARGS_CASES): Handle OPTION_BTI_NOWARN.

>      * testsuite/ld-aarch64/aarch64-elf.exp: Add all the tests below.

>      * testsuite/ld-aarch64/bti-plt-1.d: New test.

>      * testsuite/ld-aarch64/bti-plt-1.s: New test.

>      * testsuite/ld-aarch64/bti-plt-2.d: New test.

>      * testsuite/ld-aarch64/bti-plt-3.d: New test.

>      * testsuite/ld-aarch64/bti-plt-4.d: New test.

>      * testsuite/ld-aarch64/bti-plt-5.d: New test.

>      * testsuite/ld-aarch64/bti-plt-so.s: New test.

>      * testsuite/ld-aarch64/bti-plt.ld: New test.


This is part of the patch series to add support for BTI and
PAC in AArch64 linker.

This patch adds a new ld command line option: --bti.
In the presence of this option, the linker enables BTI with the
GNU_PROPERTY_AARCH64_FEATURE_1_BTI feature. It also uses the BTI
enabled PLTs and marks with DT_AARCH64_BTI_PLT. This also gives a
warning in case of missing gnu notes for BTI in inputs.
All these are made according to the new AArch64 ELF ABI
https://developer.arm.com/docs/ihi0056/latest/elf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4

Build and regression tests all pass on aarch64-none-linux-gnu and
new tests are added.

Is this ok for trunk?

Thanks
Sudi

*** bfd/ChangeLog ***

2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

	* elfnn-aarch64.c (elfNN_aarch64_merge_gnu_properties): Give out
	warning with --bti and mising BTI NOTE SECTION.

*** ld/ChangeLog ***

2019-xx-xx  Sudakshina Das  <sudi.das@arm.com>

	* NEWS: Document --bti.
	* emultempl/aarch64elf.em (OPTION_BTI_WARN): Define.
	(PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS): Add --bti.
	(PARSE_AND_LIST_ARGS_CASES): Handle OPTION_BTI_WARN.
	* testsuite/ld-aarch64/aarch64-elf.exp: Add below tests.
	* testsuite/ld-aarch64/bti-plt-6.d: New test.
	* testsuite/ld-aarch64/bti-plt-7.d: New test.

Patch

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 66fe86bbac45f2de1bce43c68036ff18ffb989a8..832de531131c82912275f2f40b475e3571cd53d5 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -9852,6 +9852,25 @@  elfNN_aarch64_merge_gnu_properties (struct bfd_link_info *info,
 {
   uint32_t prop
     = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop;
+
+  /* If output has been marked with BTI using command line argument, give out
+     warning if necessary.  */
+  if ((prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
+      && (!elf_aarch64_tdata (info->output_bfd)->no_enable_bti_warn))
+    {
+      if ((aprop && !(aprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
+	  || (bprop && !(bprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
+	  /* If either property is NULL, it means its bfd did not have any
+	     property.  */
+	  || !aprop || !bprop)
+	{
+	  _bfd_error_handler (_("warning: BTI turned on by --bti when "
+				"all inputs do not have BTI in NOTE "
+				"section. If this was intentional use "
+				"--bti-nowarn to turn off the warning."));
+	}
+    }
+
   return  _bfd_aarch64_elf_merge_gnu_properties (info, abfd, aprop,
 						 bprop, prop);
 }
diff --git a/ld/NEWS b/ld/NEWS
index 31731219ad546483ae92a7e32862986627bfc4d4..e19870f741ad072d89e4f72a1c96d2903ad9d3fd 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -13,6 +13,10 @@  Changes in 2.33:
 * Add --bti-nowarn for AArch64 to enable GNU_PROPERTY_AARCH64_FEATURE_1_BTI
   on output without any warnings and use PLTs protected with BTI.
 
+* Add --bti for AArch64 to enable GNU_PROPERTY_AARCH64_FEATURE_1_BTI
+  on output while warning about missing GNU_PROPERTY_AARCH64_FEATURE_1_BTI
+  on inputs and use PLTs protected with BTI.
+
 Changes in 2.32:
 
 * Report property change in linker map file when merging GNU properties.
diff --git a/ld/emultempl/aarch64elf.em b/ld/emultempl/aarch64elf.em
index 146bfad31fd299ef5c170b269e86afd0f3e1f5b9..c2db3e9e531930f0659197219369da1ddb04275c 100644
--- a/ld/emultempl/aarch64elf.em
+++ b/ld/emultempl/aarch64elf.em
@@ -373,6 +373,7 @@  PARSE_AND_LIST_PROLOGUE='
 #define OPTION_FIX_ERRATUM_843419	314
 #define OPTION_NO_APPLY_DYNAMIC_RELOCS	315
 #define OPTION_BTI_NOWARN		316
+#define OPTION_BTI_WARN			317
 '
 
 PARSE_AND_LIST_SHORTOPTS=p
@@ -387,6 +388,7 @@  PARSE_AND_LIST_LONGOPTS='
   { "fix-cortex-a53-843419", no_argument, NULL, OPTION_FIX_ERRATUM_843419},
   { "no-apply-dynamic-relocs", no_argument, NULL, OPTION_NO_APPLY_DYNAMIC_RELOCS},
   { "bti-nowarn", no_argument, NULL, OPTION_BTI_NOWARN},
+  { "bti", no_argument, NULL, OPTION_BTI_WARN},
 '
 
 PARSE_AND_LIST_OPTIONS='
@@ -408,6 +410,7 @@  PARSE_AND_LIST_OPTIONS='
   fprintf (file, _("  --fix-cortex-a53-843419      Fix erratum 843419\n"));
   fprintf (file, _("  --no-apply-dynamic-relocs    Do not apply link-time values for dynamic relocations\n"));
   fprintf (file, _("  --bti-nowarn                 Turn on Branch Target Identification mechanism and generate PLTs with BTI. Generate no warnings for missing BTI on inputs\n"));
+  fprintf (file, _("  --bti                        Turn on Branch Target Identification mechanism and generate PLTs with BTI. Generate warnings for missing BTI on inputs\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES='
@@ -444,6 +447,11 @@  PARSE_AND_LIST_ARGS_CASES='
       bti_type = BTI_NOWARN;
       break;
 
+    case OPTION_BTI_WARN:
+      plt_type |= PLT_BTI;
+      bti_type = BTI_WARN;
+      break;
+
     case OPTION_STUBGROUP_SIZE:
       {
 	const char *end;
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index ed0bca5b081c5c016b3f8e96619b76820aa1525d..906534b230c8905fb97a6739e1c1411683455fe3 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -400,3 +400,5 @@  run_ld_link_tests $aarch64elflinktests
 run_dump_test "bti-plt-3"
 run_dump_test "bti-plt-4"
 run_dump_test "bti-plt-5"
+run_dump_test "bti-plt-6"
+run_dump_test "bti-plt-7"
diff --git a/ld/testsuite/ld-aarch64/bti-plt-6.d b/ld/testsuite/ld-aarch64/bti-plt-6.d
new file mode 100644
index 0000000000000000000000000000000000000000..0f94e89ba227abbcf2d01b0b0fd0c5be12db2f5c
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-plt-6.d
@@ -0,0 +1,15 @@ 
+#name: Warn with one missing GNU NOTE BTI input
+#source: property-bti-pac1.s
+#source: property-bti-pac2.s
+#as: -mabi=lp64 -defsym __property_pac__=1
+#ld: -shared --bti
+#warning: .*: warning: BTI turned on by --bti.*$
+#readelf: -n
+
+# Should warn about the missing input BTI NOTE but should
+# still mark output as BTI
+
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size	Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: BTI, PAC
diff --git a/ld/testsuite/ld-aarch64/bti-plt-7.d b/ld/testsuite/ld-aarch64/bti-plt-7.d
new file mode 100644
index 0000000000000000000000000000000000000000..e4fbac4d87d746d514d109b80ccc0d0105ef444d
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-plt-7.d
@@ -0,0 +1,15 @@ 
+#name: Warn when neither inputs has GNU NOTE BTI
+#source: bti-plt-1.s
+#source: bti-plt-2.s
+#as: -mabi=lp64
+#ld: -shared --bti
+#warning: .*: warning: BTI turned on by --bti.*$
+#readelf: -n
+
+# Should warn about the missing input BTI NOTE but should
+# still mark output as BTI
+
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size	Description
+  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
+      Properties: AArch64 feature: BTI