4.2.1.6 The dynamic-tags test

  Problem:  Unprotected AArch64 binaries are vulnerable to ROP/JOP style attacks
  Fix By:   Compile with -mbranch-protection=standard
  Waive If: Not running on AArch64
  Waive If: The application will not run on Fedora 35 or later.
  Waive If: The application will not run on newer AArch64 cores.

  Example:  FAIL: dynamic tags test because BTI_PLT and PAC_PLT flags missing from the dynamic tags
  Example:  FAIL: dynamic tags test because BTI_PLT flag is missing from the dynamic tags
  Example:  FAIL: dynamic tags test because PAC_PLT flag is missing from the dynamic tags
  Example:  FAIL: dynamic tags test because no dynamic tags found

AArch64 processors are vulnerable to a class of attack known as ROP and JOP style attacks. Preventing this kind of exploit requires assistance from the hardware itself, in the form of new instructions that need to be inserted by the compiler, and new bits in the core’s status that need to be set.

This test checks to see if executable binaries have been marked as supporting the necessary security features to prevent this kind of attack. (The BTI_PLT and PAC_PLT flags mentioned in the failure messages). If they are marked then the runtime loader can enable the features in the processor core. This marking is done by setting flags in the tags found in the dynamic section of the executable. If the flags are missing then the executable is considered to be unprotected.

The security features are enabled by compiling with the -mbranch-protection=standard gcc command line option.

Note - these security features are only found on newer versions of the AArch64 architecture, and they need a compiler and a loader that will support them. Currently this means Fedora 35 or later, but not RHEL-8 or RHEL-9.

If an assembler source file is used as part of an application then it too needs to be updated. Any location in the source code where an indirect branch or function call can land must now have BTI as the first instruction executed. This instruction is safe to use even in code that will not be executed in a BTI-enabled environment as it translates into a no-op instruction if not needed.

In addition the assembler needs a note to indicate that it now supports BTI. This note can be added via including this code snippet in the sources:

	.pushsection	.note.gnu.property, "a"
	.align	3
	.word	2f - 1f
	.word	4f - 3f
	.word	5            /* NT_GNU_PROPERTY_TYPE_0 */
1:	.asciz	"GNU"

2:	.align	3
3:	.word	0xc0000000   /* type: GNU_PROPERTY_AARCH64_FEATURE_1_AND */
	.word	6f - 5f	     /* size */
5:	.word	1            /* value: GNU_PROPERTY_AARCH64_FEATURE_1_BTI */

6:	.align	3
4:	.popsection

Note - this test is the inverse of the The not-dynamic-tags test test and directly related to the The branch-protection test test.

Note - this test is automatically enabled if one of the following profile options is used:

--profile=rawhide
--profile=f43
--profile=f42
--profile=f41
--profile=f40
--profile=f39
--profile=f38
--profile=f37
--profile=f36
--profile=el10

The test is automatically disabled if one of the other profile options is used, ie:

--profile=el7
--profile=el8
--profile=el9
--profile=f35

If necessary the test can be disabled via the --skip-dynamic-tags option and re-enabled via the --test-dynamic-tags option.