[00/12] aarch64: branch protection support

Message ID 20200430173458.GV29015@arm.com
Headers
Series aarch64: branch protection support |

Message

Szabolcs Nagy April 30, 2020, 5:34 p.m. UTC
  Indirect branch target identification (BTI, armv8.5-a) and return
address signing using pointer authentication (PAC-RET, armv8.3-a)
can be used for security hardening against some control flow hijack
attacks.

In gcc these are exposed via -mbranch-protection=bti+pac-ret which
is the same as -mbranch-protection=standard and gcc can be configured
via --enable-standard-branch-protection to use them by default.

BTI requires libc support: it is an opt-in feature per ELF module
via a GNU property NOTE that the dynamic linker has to check and
mprotect the executable pages with PROT_BTI. And libc objects that
are statically linked into user binaries must be BTI compatible
for the GNU property NOTE to be present. (The property NOTE is
handled by linux for static linked executables and for the ld.so.)

PAC-RET does not require libc runtime support, but, just like BTI,
it can be used in libc binaries.

The patch series is not finalized:

- PAC-RET may need to be configure checked and disabled if user
  did not explicitly configured glibc with standard branch
  protection, because it can have compatibility problems:
  requires recent libgcc for working unwinding.

- The GNU property ELF marking can trigger ugly linker warnings
  before binutils-2.33 so probably BTI should not be added
  unconditionally either.

- Changed the logic of how NOTEs are processed (which may
  affect x86 too) because I only wanted to handle PT_GNU_PROPERTY
  not PT_NOTE on aarch64. (Otherwise note handling is similar
  to the x86 code.)

- Some changes may be better handled by target hooks
  (e.g. moved abi-note.S to C and copied the syscall template
  just to add the BTI property NOTE)

- The -pg profiling abi with PAC-RET is not finalized: _mcount
  currently may get a signed return address as argument so either
  it has to remove it or gcc -pg has to be fixed not to pass
  such argument to _mcount. (glibc gmon tests currently fail)
  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94791

- Redefined RETURN_ADDRESS for aarch64, this may change depending
  on the ruling about
  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94891

- I was considering separating out the bits that are necessary for
  just enabling BTI to work in user binaries from changes that are
  needed for building glibc itself with BTI, but decided against
  it as it needs more work, cannot work with static linking and
  unlikely to be very useful.

Ran cross tests in qemu using the linux bti patches from
git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
i did some changes to the posted patches and rerunning the tests
now, the previous results:

FAIL: gmon/tst-gmon-gprof
FAIL: gmon/tst-gmon-pie-gprof
FAIL: gmon/tst-gmon-static-gprof
	_mcount ABI with pac-ret
FAIL: misc/tst-atomic
FAIL: nptl/tst-cancel7
FAIL: nptl/tst-cancelx7
	not reproducible issues
FAIL: elf/tst-ldconfig-ld_so_conf-update
	not sure, likely something in my cross test setup makes
	/etc/ld.so.cache not being reread after a change (nfs?).
FAIL: elf/tst-audit14
FAIL: elf/tst-audit15
FAIL: elf/tst-audit16
	missing /dev/stdout (even if i have /dev/stdout
	these fail because reading /proc/self/fd/1 fails
	in my cross test setup)
FAIL: io/ftwtest
FAIL: libio/tst-wfile-sync
FAIL: nptl/test-cond-printers
FAIL: nptl/test-condattr-printers
FAIL: nptl/test-mutex-printers
FAIL: nptl/test-mutexattr-printers
FAIL: nptl/test-rwlock-printers
FAIL: nptl/test-rwlockattr-printers
	cross test issues

Sudakshina Das (3):
  aarch64: Add BTI landing pads to assembly code
  aarch64: support BTI enabled binaries
  aarch64: Configure option to build glibc with branch protection

Szabolcs Nagy (9):
  elf.h: Add PT_GNU_PROPERTY
  elf.h: add aarch64 property definitions
  aarch64: Rename place holder .S files to .c
  aarch64: fix swapcontext for BTI
  aarch64: fix RTLD_START for BTI
  aarch64: fix syscalls for BTI
  Rewrite abi-note.S in C.
  aarch64: Add pac-ret support to asm files
  aarch64: redefine RETURN_ADDRESS to strip PAC

 configure                                     |  14 +-
 configure.ac                                  |   6 +
 csu/{abi-note.S => abi-note.c}                |  24 +--
 elf/dl-load.c                                 |   2 +
 elf/elf.h                                     |   7 +
 elf/rtld.c                                    |   2 +
 sysdeps/aarch64/Makefile                      |   8 +
 sysdeps/aarch64/__longjmp.S                   |   1 +
 .../aarch64/{bsd-_setjmp.S => bsd-_setjmp.c}  |   0
 .../aarch64/{bsd-setjmp.S => bsd-setjmp.c}    |   0
 sysdeps/aarch64/configure                     |  31 ++++
 sysdeps/aarch64/configure.ac                  |  19 ++
 sysdeps/aarch64/crti.S                        |  12 ++
 sysdeps/aarch64/crtn.S                        |  10 ++
 sysdeps/aarch64/dl-bti.c                      |  54 ++++++
 sysdeps/aarch64/dl-machine.h                  |   5 +-
 sysdeps/aarch64/dl-prop.h                     | 170 ++++++++++++++++++
 sysdeps/aarch64/dl-tlsdesc.S                  |  13 ++
 sysdeps/aarch64/dl-trampoline.S               |  19 +-
 sysdeps/aarch64/linkmap.h                     |   1 +
 sysdeps/aarch64/memchr.S                      |   1 +
 sysdeps/aarch64/memcmp.S                      |   1 +
 sysdeps/aarch64/memcpy.S                      |   1 +
 sysdeps/aarch64/{memmove.S => memmove.c}      |   0
 sysdeps/aarch64/memrchr.S                     |   1 +
 sysdeps/aarch64/memset.S                      |   1 +
 sysdeps/aarch64/multiarch/memchr_nosimd.S     |   1 +
 sysdeps/aarch64/multiarch/memcpy_falkor.S     |   1 +
 sysdeps/aarch64/multiarch/memcpy_thunderx.S   |   1 +
 sysdeps/aarch64/multiarch/memcpy_thunderx2.S  |   1 +
 sysdeps/aarch64/multiarch/memmove_falkor.S    |   1 +
 sysdeps/aarch64/multiarch/memset_base64.S     |   1 +
 sysdeps/aarch64/multiarch/memset_kunpeng.S    |   1 +
 sysdeps/aarch64/multiarch/strlen_asimd.S      |   1 +
 sysdeps/aarch64/rawmemchr.S                   |   1 +
 sysdeps/aarch64/setjmp.S                      |   1 +
 sysdeps/aarch64/start.S                       |   2 +
 sysdeps/aarch64/strchr.S                      |   1 +
 sysdeps/aarch64/strchrnul.S                   |   1 +
 sysdeps/aarch64/strcmp.S                      |   1 +
 sysdeps/aarch64/strcpy.S                      |   1 +
 sysdeps/aarch64/strlen.S                      |   1 +
 sysdeps/aarch64/strncmp.S                     |   1 +
 sysdeps/aarch64/strnlen.S                     |   1 +
 sysdeps/aarch64/strrchr.S                     |   1 +
 sysdeps/aarch64/sysdep.h                      |  53 +++++-
 sysdeps/unix/sysv/linux/aarch64/__read_tp.S   |   1 +
 sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h  |   1 +
 sysdeps/unix/sysv/linux/aarch64/bits/mman.h   |  31 ++++
 sysdeps/unix/sysv/linux/aarch64/clone.S       |   1 +
 .../unix/sysv/linux/aarch64/cpu-features.c    |   3 +
 .../unix/sysv/linux/aarch64/cpu-features.h    |   1 +
 sysdeps/unix/sysv/linux/aarch64/getcontext.S  |   1 +
 sysdeps/unix/sysv/linux/aarch64/ioctl.S       |   1 +
 .../unix/sysv/linux/aarch64/libc-__read_tp.S  |   1 +
 sysdeps/unix/sysv/linux/aarch64/setcontext.S  |   1 +
 sysdeps/unix/sysv/linux/aarch64/swapcontext.S |  15 +-
 .../sysv/linux/aarch64/syscall-template.S     |  20 +++
 sysdeps/unix/sysv/linux/aarch64/syscall.S     |   1 +
 sysdeps/unix/sysv/linux/aarch64/umount2.S     |  25 +++
 sysdeps/unix/sysv/linux/aarch64/vfork.S       |   1 +
 61 files changed, 564 insertions(+), 16 deletions(-)
 rename csu/{abi-note.S => abi-note.c} (85%)
 rename sysdeps/aarch64/{bsd-_setjmp.S => bsd-_setjmp.c} (100%)
 rename sysdeps/aarch64/{bsd-setjmp.S => bsd-setjmp.c} (100%)
 create mode 100644 sysdeps/aarch64/dl-bti.c
 create mode 100644 sysdeps/aarch64/dl-prop.h
 rename sysdeps/aarch64/{memmove.S => memmove.c} (100%)
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/bits/mman.h
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/syscall-template.S
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/umount2.S
  

Comments

Szabolcs Nagy May 4, 2020, 11:27 a.m. UTC | #1
The 04/30/2020 18:34, Szabolcs Nagy wrote:
> FAIL: misc/tst-atomic

on a closer look this seems to be a glibc test bug:

 529   mem = 14;
 530   expected = 14;
 531   if (!atomic_compare_exchange_weak_relaxed (&mem, &expected, 25)
 532       || mem != 25 || expected != 14)
 533     {
 534       puts ("atomic_compare_exchange_weak_relaxed test 1 failed");
 535       ret = 1;
 536     }

compare exchange may fail intermittently e.g.
because of scheduling events, so the caller
should retry. i opened
https://sourceware.org/bugzilla/show_bug.cgi?id=25919

> FAIL: nptl/tst-cancel7
> FAIL: nptl/tst-cancelx7
> 	not reproducible issues