RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]

Andrew Haley aph at openjdk.java.net
Mon Nov 15 10:15:40 UTC 2021


On Mon, 15 Nov 2021 09:07:11 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 with a new target base due to a merge or a rebase. The pull request now contains eight commits:
> 
>  - Merge master
>  - Document pauth functions && remove OS split
>  - Update UseROPProtection description
>  - Simplify branch protection configure check
>  - 8264130: PAC-RET protection for Linux/AArch64
>    
>    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.
>  - Add PAC assembly instructions
>  - Add AArch64 ROP protection runtime flag
>  - Build with branch protection

src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp line 452:

> 450: 
> 451:   // only r0 is valid at this time, all other registers have been destroyed by the runtime call
> 452:   __ invalidate_registers(false, true, true, true, true, true);

Not so: `lr` is live.

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

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



More information about the build-dev mailing list