This patch enables BTI branch protection for runtime part on Linux/aarch64 
platform.

Motivation

1. Since Fedora 33, glibc+kernel are PAC/BTI enabled by default. User-level 
packages can gain additional hardening by compiling with the GCC/Clang flag 
`-mbranch-protection=flag`. See [1].

2. In JDK-8277204 [2], `--enable-branch-protection` was introduced as one VM 
configure flag, which would pass `-mbranch-protection=standard` compilation 
flags to all c/c++ files. Note that `standard` turns on both `pac-ret` and 
`bti` branch protections. For more details about code reuse attacks and 
hardware-assisted branch protections on AArch64, see [3].

However, we checked the `.note.gnu.property` section of all the shared 
libraries under `jdk/lib` on Fedora 40, and found that only libjvm.so didn't 
set these two target feature bits:


  GNU_PROPERTY_AARCH64_FEATURE_1_BTI
  GNU_PROPERTY_AARCH64_FEATURE_1_PAC


Note-1: BTI is an all or nothing property for a link unit [4]. That is, 
libjvm.so is not BTI-enabled.

Note-2: PAC bit in `.note.gnu.property` section is used to protect `.got.plt` 
table. It's independent of whether the relocatable objects use PAC or not.

Goal

Hence, this patch aims to set PAC/BTI feature bits of the `.note.gnu.property` 
section for libjvm.so.

Implementation

Task-1: find out the problematic input objects

>From [5], "Static linkers processing ELF relocatable objects must set the 
>feature bit in the output object or image only if all the input objects have 
>the corresponding feature bit set." Hence we suspect that the root cause is 
>probably that the PAC/BTI feature bits are not set only for some input objects 
>of libjvm.so.

In order to find out these inputs, we passed `--force-bti` linker flag [4] in 
my local test. This linker flag would warn if any input object does not have 
GNU_PROPERTY_AARCH64_FEATURE_1_BTI. We got the following list:


  src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S
  src/hotspot/os_cpu/linux_aarch64/copy_linux_aarch64.S
  src/hotspot/os_cpu/linux_aarch64/safefetch_linux_aarch64.S
  src/hotspot/os_cpu/linux_aarch64/threadLS_linux_aarch64.S


Task-2: add `.note.gnu.property` section for these assembly files

As mentioned in Motivation-2 part, `-mbranch-protection=standard` is passed to 
compile c/c++ files but these assembly files are missed.

In this patch, we also pass `-mbranch-protection=standard` flag to assembler 
(See the update in flags-cflags.m4 and flags-other.m4), and add 
`.note.gnu.property` section at the end of these assembler files.

With this change, we can see PAC/BTI feature bits in the final libjvm.so.

Task-3: add BTI landing pads for hand written assembly

In the local test on Fedora 40 with PAC/BTI-capable hardware, we got `SIGILL` 
error, which is one typical BTI error (branch target exception). The root cause 
is that we should add the missing BTI landing pads for hand written assembly in 
hotspot.

File-1 copy_aarch64.hpp: It's a switch-case statement and we add `bti j` for 
these indirect jumps.

File-2 atomic_linux_aarch64.S: We add landings pads `bti c` at the function 
entries.

File-3 copy_linux_aarch64.S: There is no need to add `bti c` at the function 
entries since they are called via `bl`. And we should handle the indirect jumps.

File-4 safefetch_linux_aarch64.S: Similar to file-3, there is no need to handle 
these function entries.

File-5 threadLS_linux_aarch64.S: No need to handle the function entry because 
`paciasp` can act as the landing pad.

Evaluation

1. jtreg test

We ran tier 1-3 jtreg tests on Fedora 40 + GCC 14 + the following AArch64 
hardware and all tests passed.


  1. w/o PAC and w/o BTI
  2. w/ PAC and w/o BTI
  3. w/ PAC and w/ BTI


We also ran the jtreg tests on Fedora 40 + Clang 18 + hardware w/ PAC and w/ 
BTI. The test passed too.

2. code size

We got about 2% code size increase before and after 
`--enbale-branch-protection` is used. This code size change looks reasonable. 
See the evaluation on glibc [6].

[1] https://fedoraproject.org/wiki/Changes/Aarch64_PointerAuthentication
[2] https://bugs.openjdk.org/browse/JDK-8277204
[3] 
https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/code-reuse-attacks-the-compiler-story
[4] https://reviews.llvm.org/D62609
[5] 
https://github.com/ARM-software/abi-aa/blob/2a70c42d62e9c3eb5887fa50b71257f20daca6f9/aaelf64/aaelf64.rst#program-property
[6] 
https://developer.arm.com/documentation/102433/0100/Applying-these-techniques-to-real-code

-------------

Commit messages:
 - 8337536: AArch64: Enable BTI branch protection for runtime part

Changes: https://git.openjdk.org/jdk/pull/20491/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=20491&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8337536
  Stats: 223 lines in 7 files changed: 199 ins; 2 del; 22 mod
  Patch: https://git.openjdk.org/jdk/pull/20491.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/20491/head:pull/20491

PR: https://git.openjdk.org/jdk/pull/20491

Reply via email to