RFR: 8277204: Implementation of JEP 8264130: PAC-RET protection for Linux/AArch64 [v8]

Andrew Haley aph at openjdk.java.net
Thu Dec 9 17:16:20 UTC 2021


On Thu, 2 Dec 2021 09:20:53 GMT, Alan Hayward <duke at openjdk.java.net> wrote:

>> 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.
>
> Alan Hayward has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Fix up UseROPProtection flag

make/autoconf/flags-cflags.m4 line 902:

> 900:   BRANCH_PROTECTION_CFLAGS=""
> 901:   UTIL_ARG_ENABLE(NAME: branch-protection, DEFAULT: auto,
> 902:       RESULT: USE_BRANCH_PROTECTION, AVAILABLE: $BRANCH_PROTECTION_AVAILABLE,

What exactly is going on here? Is it that if the host compiler has "branch protection" supported, we will build with it on by default? if so, no, we don't want to do that. For now, branch protection should be an explicit opt in.

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

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



More information about the build-dev mailing list