PAC is an optional feature in AArch64 8.3 and is compulsory in v9. One
of its uses is to protect against ROP based attacks. This is done by
signing the Link Register whenever it is stored on the stack, and
authenticating the value when it is loaded back from the stack. If an
attacker were to try to change control flow by editing the stack then
the authentication check of the Link Register will fail, causing a
segfault when the function returns.

On a system with PAC enabled, it is expected that all applications will
be compiled with ROP protection. Fedora 33 and upwards already provide
this. By compiling for ARMv8.0, GCC and LLVM will only use the set of
PAC instructions that exist in the NOP space - on hardware without PAC,
these instructions act as NOPs, allowing backward compatibility for
negligible performance cost (2 NOPs per non-leaf function).

Hardware is currently limited to the Apple M1 MacBooks. All testing has
been done within a Fedora Docker image. A run of SpecJVM showed no
difference to that of noise - which was surprising.

The most important part of this patch is simply compiling using branch
protection provided by GCC/LLVM. This protects all C++ code from being
used in ROP attacks, removing all static ROP gadgets from use.

The remainder of the patch adds ROP protection to runtime generated
code, in both stubs and compiled Java code. Attacks here are much harder
as ROP gadgets must be found dynamically at runtime. If/when AOT
compilation is added to JDK, then all stubs and compiled Java will be
susceptible ROP gadgets being found by static analysis and therefore
potentially as vulnerable as C++ code.

There are a number of places where the VM changes control flow by
rewriting the stack or otherwise. I’ve done some analysis as to how
these could also be used for attacks (which I didn’t want to post here).
These areas can be protected ensuring the pointers to various stubs and
entry points are stored in memory as signed pointers. These changes are
simple to make (they can be reduced to a type change in common code and
a few addition sign/auth calls in the backend), but there a lot of them
and the total code change is fairly large. I’m happy to provide a few
work in progress patches.

In order to match the security benefits of the Apple Arm64e ABI across
the whole of JDK, then all the changes mentioned above would be
required.

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

Commit messages:
 - 8264130: PAC-RET protection for Linux/AArch64
 - Add PAC assembly instructions
 - Add AArch64 ROP protection runtime flag
 - Build with branch protection

Changes: https://git.openjdk.java.net/jdk/pull/6334/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=6334&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8264130
  Stats: 1273 lines in 25 files changed: 457 ins; 20 del; 796 mod
  Patch: https://git.openjdk.java.net/jdk/pull/6334.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/6334/head:pull/6334

PR: https://git.openjdk.java.net/jdk/pull/6334

Reply via email to