On Tue, 22 Feb 2022 14:35:19 GMT, Alan Hayward <d...@openjdk.org> 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 34 commits:
> 
>  - Merge master
>  - Merge master
>  - Merge master
>  - Error on -XX:-PreserveFramePointer -XX:UseBranchProtection=pac-ret
>  - Add comments to enter calls
>  - Set PreserveFramePointer if use_rop_protection is set
>  - Merge enter_subframe into enter
>  - Review fixups
>  - Documentation updates
>  - Update copyrights to 2022
>  - ... and 24 more: https://git.openjdk.org/jdk/compare/022d8070...c4e0ee31

src/hotspot/cpu/aarch64/vm_version_aarch64.cpp line 413:

> 411:   }
> 412: 
> 413:   if (UseBranchProtection == nullptr || strcmp(UseBranchProtection, 
> "none") == 0) {

My understanding is that `UseBranchProtection` requires JIT compiler 
integration. This is currently missing in Graal. The logic that decides if it 
should be enabled by default needs to take JVMCI into consideration, much like 
the call to `JVMCIGlobals::check_jvmci_supported_gc` determines if JVMCI 
supports the configured GC.

Thanks to @gilles-duboscq for alerting me to this change.

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

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

Reply via email to