Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v5]
> 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 three additional commits since the last revision: - Rename pauth_authenticate_or_strip_return_address - Fix windows aarch64 by restoring pauth file split - Don't keep LR live across restore_live_registers - Changes: - all: https://git.openjdk.java.net/jdk/pull/6334/files - new: https://git.openjdk.java.net/jdk/pull/6334/files/2c27eb5e..dbd6bda2 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk=6334=04 - incr: https://webrevs.openjdk.java.net/?repo=jdk=6334=03-04 Stats: 318 lines in 6 files changed: 233 ins; 70 del; 15 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
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]
On Mon, 15 Nov 2021 11:54:09 GMT, Andrew Dinn wrote: > pauth_strip_verifiable That name works for me. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]
On Mon, 15 Nov 2021 11:08:57 GMT, Andrew Haley wrote: >>>whether this function authenticates or strips the address depends only on >>>debugging? >> >> Yes. We only need to strip the value, because we're not jumping to the lr >> value, only viewing it. >> >> The interface is different to a strip (as we need to pass in the modifier). >> >> How about something like pauth_authenticate_fast() ? or >> pauth_authenticate_unsafe() ? >> >> Alternatively, this function is only called by the functions in Frame, so >> the frequency of use is probably low enough (compared to the sign/auth every >> function) that it's not going to cause any performance issues. So, could >> just replace with calls to pauth_authenticate. I think that might be the >> best option. > > A simple rule here: function names go with what the release version does. So > I'd go with the actual purpose, which is `pauth_strip_addr_for_debuginfo()`. > That's right, isn't it? You only want this thing for stack traces, logs, etc. This function is used by the frame code. So, that means it is used for all stack walks which are far from being simply cosmetic/ornamental. The runtime will rely on this for various different types of thread housekeeping. The difference here is that in product mode this simply strips auth bits whereas in debug mode it actually authenticates as it strips to give extra verification. So, your suggested name is quite misleading. Likewise Alan's suggested names is misleading because the primary product operation is to strip not authenticate. How about pauth_strip_verifiable? and a comment saying that it differs from pauth_strip by actually authenticating when debug is enabled. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]
On Mon, 15 Nov 2021 11:30:35 GMT, Andrew Haley wrote: >> In the original code: >> *save r0 to the lr location on the stack >> *restore_live_registers >> *Standard return: remove stack frame, load lr and fp off the stack, jump to >> lr. >> >> With PAC it would now be: >> *Sign r0 then save it to the lr location on the stack >> *restore_live_registers >> *Standard return: remove stack frame, load lr and fp off the stack, auth lr, >> jump to lr. >> >> After reading the code in restore_live_registers, it doesn't touch lr and so >> seemed odd to have the save to the stack, only to restore it directly >> afterwards. > > That's an optimization, though. You shouldn't need to read the code in > `restore_live_registers()` to see if it's safe to keep the return address in > LR: at best it's pathological coupling, in the sense that the correctness of > this code depends on the internal details of `restore_live_registers()`. > Let's keep LR live ranges as short as possible. Ok, that's fine, I'll update it (It'll simplify the total code diff too). - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]
On Mon, 15 Nov 2021 11:21:37 GMT, Alan Hayward wrote: >> src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp line 452: >> >>> 450: // patch the return address, this stub will directly return to the >>> exception handler >>> 451: __ str(r0, Address(rfp, 1*BytesPerWord)); >>> 452: >> >> Please explain the reason for this change, that leaves `lr` live across >> `restore_live_registers()`. > > In the original code: > *save r0 to the lr location on the stack > *restore_live_registers > *Standard return: remove stack frame, load lr and fp off the stack, jump to > lr. > > With PAC it would now be: > *Sign r0 then save it to the lr location on the stack > *restore_live_registers > *Standard return: remove stack frame, load lr and fp off the stack, auth lr, > jump to lr. > > After reading the code in restore_live_registers, it doesn't touch lr and so > seemed odd to have the save to the stack, only to restore it directly > afterwards. That's an optimization, though. You shouldn't need to read the code in `restore_live_registers()` to see if it's safe to keep the return address in LR: at best it's pathological coupling, in the sense that the correctness of this code depends on the internal details of `restore_live_registers()`. Let's keep LR live ranges as short as possible. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]
On Mon, 15 Nov 2021 10:15:41 GMT, Andrew Haley wrote: >> 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: // patch the return address, this stub will directly return to the >> exception handler >> 451: __ str(r0, Address(rfp, 1*BytesPerWord)); >> 452: > > Please explain the reason for this change, that leaves `lr` live across > `restore_live_registers()`. In the original code: *save r0 to the lr location on the stack *restore_live_registers *Standard return: remove stack frame, load lr and fp off the stack, jump to lr. With PAC it would now be: *Sign r0 then save it to the lr location on the stack *restore_live_registers *Standard return: remove stack frame, load lr and fp off the stack, auth lr, jump to lr. After reading the code in restore_live_registers, it doesn't touch lr and so seemed odd to have the save to the stack, only to restore it directly afterwards. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]
On Mon, 15 Nov 2021 10:58:06 GMT, Alan Hayward wrote: >> src/hotspot/cpu/aarch64/pauth_aarch64.hpp line 132: >> >>> 130: // Authenticate or strip a return value. Use for efficiency and only >>> when the safety of the data >>> 131: // isn't an issue - for example when viewing the stack. >>> 132: // >> >> So, whether this function authenticates or strips the address depends only >> on debugging? The vague name makes the callers hard to read. > >>whether this function authenticates or strips the address depends only on >>debugging? > > Yes. We only need to strip the value, because we're not jumping to the lr > value, only viewing it. > > The interface is different to a strip (as we need to pass in the modifier). > > How about something like pauth_authenticate_fast() ? or > pauth_authenticate_unsafe() ? > > Alternatively, this function is only called by the functions in Frame, so the > frequency of use is probably low enough (compared to the sign/auth every > function) that it's not going to cause any performance issues. So, could just > replace with calls to pauth_authenticate. I think that might be the best > option. A simple rule here: function names go with what the release version does. So I'd go with the actual purpose, which is `pauth_strip_addr_for_debuginfo()`. That's right, isn't it? You only want this thing for stack traces, logs, etc. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]
On Mon, 15 Nov 2021 10:20:15 GMT, Andrew Haley wrote: >whether this function authenticates or strips the address depends only on >debugging? Yes. We only need to strip the value, because we're not jumping to the lr value, only viewing it. The interface is different to a strip (as we need to pass in the modifier). How about something like pauth_authenticate_fast() ? or pauth_authenticate_unsafe() ? Alternatively, this function is only called by the functions in Frame, so the frequency of use is probably low enough (compared to the sign/auth every function) that it's not going to cause any performance issues. So, could just replace with calls to pauth_authenticate. I think that might be the best option. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]
On Wed, 10 Nov 2021 15:01:51 GMT, Alan Hayward wrote: >> src/hotspot/os_cpu/bsd_aarch64/pauth_bsd_aarch64.inline.hpp line 25: >> >>> 23: */ >>> 24: >>> 25: #ifndef OS_CPU_BSD_AARCH64_PAUTH_BSD_AARCH64_INLINE_HPP >> >> Are these two files different enough to separate them for BSD and Linux? > > My motivation was to avoid having any ifdefs - but we need one anyway for the > apple ifdef. > > If I merged the two we would end up with just the contents of the BSD version > of the file. > > There is also the windows version of the file, which for now has empty > functions. If PAC in windows is added, that'll either use the same code or > maybe Windows will provide an API (like the Apple one). Merging everything > would mean windows gains the UseROPProtection check. >Are these two files different enough to separate them for BSD and Linux? Merging these files then broke everything for windows (because the asm function is different). Having a "ifdef apple, elseif windows else" doesn't really make sense, so I'll split the files out again. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]
On Mon, 15 Nov 2021 09:07:11 GMT, Alan Hayward 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
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]
On Mon, 15 Nov 2021 09:07:11 GMT, Alan Hayward 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
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]
On Mon, 15 Nov 2021 09:07:11 GMT, Alan Hayward 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
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]
On Mon, 15 Nov 2021 09:07:11 GMT, Alan Hayward 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
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]
On Mon, 15 Nov 2021 09:07:11 GMT, Alan Hayward 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
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v4]
> 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
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v3]
On Fri, 12 Nov 2021 16:18:04 GMT, Alan Hayward 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 two additional > commits since the last revision: > > - Document pauth functions && remove OS split > - Update UseROPProtection description src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp line 5254: > 5252: // Also use before signing to check that the pointer is valid and > hasn't already been signed. > 5253: // > 5254: void MacroAssembler::check_return_address(Register return_reg) { This commentary is excellent. Thanks. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 08:48:07 GMT, Alan Hayward 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: > > Simplify branch protection configure check *Updated UseROPProtection message *Moved pauth functions into single file *Added comments *Removed superfluous modifier arg from macroassembler funcs - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v3]
> 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 two additional commits since the last revision: - Document pauth functions && remove OS split - Update UseROPProtection description - Changes: - all: https://git.openjdk.java.net/jdk/pull/6334/files - new: https://git.openjdk.java.net/jdk/pull/6334/files/29471d30..25e62492 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk=6334=02 - incr: https://webrevs.openjdk.java.net/?repo=jdk=6334=01-02 Stats: 369 lines in 9 files changed: 129 ins; 219 del; 21 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
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 18:07:37 GMT, Andrew Haley wrote: > > > Am I right is saying that for Macos, all generated code is remapped RO > > > before execution? > > > > > > Ah, no, it seems the code cache is not RWX all the time as far as Java > > threads are concerned. The Macos/AArch64 code is strategically calling > > pthread_jit_write_protect_np at Java <-> JVM transition points. > > And this requires magic kernel support. I did mention it to a kernel engineer > who wasn't very impressed, but I think it's pretty cool. It's possible to emulate this to some extent with memory protection keys on POWER and (recent) x86. See `pkey_alloc`. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 16:31:41 GMT, Andrew Dinn wrote: > > Am I right is saying that for Macos, all generated code is remapped RO > > before execution? > > Ah, no, it seems the code cache is not RWX all the time as far as Java > threads are concerned. The Macos/AArch64 code is strategically calling > pthread_jit_write_protect_np at Java <-> JVM transition points. And this requires magic kernel support. I did mention it to a kernel engineer who wasn't very impressed, but I think it's pretty cool. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 14:59:32 GMT, Andrew Dinn wrote: >> I did mean the description, not the flag name. > > Yes, understood. I too was talking about the description even though I > introduced my comment by talking about what the flag does. `"Protect branches against ROP attacks".` - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 15:30:29 GMT, Alan Hayward wrote: > Am I right is saying that for Macos, all generated code is remapped RO before > execution? Ah, no, it seems the code cache is not RWX all the time as far as Java threads are concerned. The Macos/AArch64 code is strategically calling pthread_jit_write_protect_np at Java <-> JVM transition points. That ensures that executable regions are executable but not writable (RX) from a Java thread when running JITted Java code and are writable but not executable (RW) when it calls into JVM code. > An additional concern I have is that if the globals data was attacked then > the UseROPProtection flag could be flipped, and all code after that point > would be generated without ROP protection. Marking all the globals data as RO > would fix that. Alternatively remove UseROPProtection and then in the > macroassembler always generate PAC code, using just the subset of > instructions that are NOPs on non-PAC hardware. Or alternatively only > generate PAC code based on a #define set at build time. Each option has its > own downsides. Globals data can legitimately be written during JVM startup (perhaps in some cases also during execution?). So, they cannot simply be marked as RO. I am not sure this concern is really warranted. If an attacker is already able to overwrite UseROPProtection then a concern over the resulting omission of JITted ROP protection seems like attending to the loud banging of the stable door while Shergar has already been diced into stew meat. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 14:52:54 GMT, Andrew Dinn wrote: > The runtime generated runtime stubs and Java method code into which this > patch may insert the required PAC instructions are written into a code cache > in a section which is mapped RW(X) all the time. It would be hard to map even > a subset of this code cache RO because generated code includes call and data > sites that need to be patched during execution. Am I right is saying that for Macos, all generated code is remapped RO before execution? An additional concern I have is that if the globals data was attacked then the UseROPProtection flag could be flipped, and all code after that point would be generated without ROP protection. Marking all the globals data as RO would fix that. Alternatively remove UseROPProtection and then in the macroassembler always generate PAC code, using just the subset of instructions that are NOPs on non-PAC hardware. Or alternatively only generate PAC code based on a #define set at build time. Each option has its own downsides. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 14:20:33 GMT, Florian Weimer wrote: > Is the code still mapped read-write all the time? That depends on what code you mean. The JVM code compiled from C++ sources is mapped RO(X) in the text section like any compiled C/C++ code. Protection of that code is covered by the changes to the build system. The runtime generated runtime stubs and Java method code into which this patch may insert the required PAC instructions are written into a code cache in a section which is mapped RW(X) all the time. It would be hard to map even a subset of this code cache RO because generated code includes call and data sites that need to be patched during execution. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 14:53:54 GMT, Florian Weimer wrote: >> I don't agree that this is incorrect, at least not for the stated reason. >> The flag switches on a protection mechanism that guards against ROP attacks. >> To my reading that does not imply it guards against all such attacks, merely >> that this is the nature of the protection it offers. >> >> The description might still be considered incorrect for an unrelated reason. >> Its use of the adjectival phrase ROP based constitutes a transferred >> epithet, conflating the symptom with the medicine. In other words, the >> protection offered is not ROP based i.e. does not rely on an ROP technique. >> What it does is protect against ROP attacks. So, I'd suggest rewording to >> >> "Enable protection of branches against ROP attacks". >> >> Florian, if you want to argue for rewording that to "Enable protection of >> branches against some categories of ROP attacks" or some other equivalently >> qualified variant please feel free to make a case. However, I don't think >> see any need to add that rider, nor any precedent in any of the other short >> descriptions provided in globals.hpp. > > I did mean the description, not the flag name. Yes, understood. I too was talking about the description even though I introduced my comment by talking about what the flag does. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 14:43:59 GMT, Andrew Dinn wrote: >> src/hotspot/cpu/aarch64/globals_aarch64.hpp line 115: >> >>> 113: range(-1, 4096) >>> \ >>> 114: product(bool, UseROPProtection, false, >>> \ >>> 115: "Use ROP based branch protection") >>> \ >> >> The description is not correct. It's protection against certain ROP-based >> attack techniques. > > I don't agree that this is incorrect, at least not for the stated reason. The > flag switches on a protection mechanism that guards against ROP attacks. To > my reading that does not imply it guards against all such attacks, merely > that this is the nature of the protection it offers. > > The description might still be considered incorrect for an unrelated reason. > Its use of the adjectival phrase ROP based constitutes a transferred epithet, > conflating the symptom with the medicine. In other words, the protection > offered is not ROP based i.e. does not rely on an ROP technique. What it does > is protect against ROP attacks. So, I'd suggest rewording to > > "Enable protection of branches against ROP attacks". > > Florian, if you want to argue for rewording that to "Enable protection of > branches against some categories of ROP attacks" or some other equivalently > qualified variant please feel free to make a case. However, I don't think see > any need to add that rider, nor any precedent in any of the other short > descriptions provided in globals.hpp. I did mean the description, not the flag name. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 14:20:20 GMT, Florian Weimer wrote: >> Alan Hayward has updated the pull request incrementally with one additional >> commit since the last revision: >> >> Simplify branch protection configure check > > src/hotspot/cpu/aarch64/globals_aarch64.hpp line 115: > >> 113: range(-1, 4096) >> \ >> 114: product(bool, UseROPProtection, false, >> \ >> 115: "Use ROP based branch protection") >> \ > > The description is not correct. It's protection against certain ROP-based > attack techniques. I don't agree that this is incorrect, at least not for the stated reason. The flag switches on a protection mechanism that guards against ROP attacks. To my reading that does not imply it guards against all such attacks, merely that this is the nature of the protection it offers. The description might still be considered incorrect for an unrelated reason. Its use of the adjectival phrase ROP based constitutes a transferred epithet, conflating the symptom with the medicine. In other words, the protection offered is not ROP based i.e. does not rely on an ROP technique. What it does is protect against ROP attacks. So, I'd suggest rewording to "Enable protection of branches against ROP attacks". Florian, if you want to argue for rewording that to "Enable protection of branches against some categories of ROP attacks" or some other equivalently qualified variant please feel free to make a case. However, I don't think see any need to add that rider, nor any precedent in any of the other short descriptions provided in globals.hpp. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 08:48:07 GMT, Alan Hayward 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: > > Simplify branch protection configure check Is the code still mapped read-write all the time? src/hotspot/cpu/aarch64/globals_aarch64.hpp line 115: > 113: range(-1, 4096) \ > 114: product(bool, UseROPProtection, false,\ > 115: "Use ROP based branch protection")\ The description is not correct. It's protection against certain ROP-based attack techniques. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 08:48:07 GMT, Alan Hayward 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: > > Simplify branch protection configure check Build changes look much better now, thanks! Build part approved; the actual code changes needs approval from others. - Marked as reviewed by ihse (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 11:52:46 GMT, Andrew Haley wrote: >> I'm thinking for references to the Arm Arm to use header titles instead of >> section numbers, as the titles should be more stable. >> >> Also probably need some description around the code in the pauth_aarch64.hpp >> too. But I want to make sure I'm not duplicating comments - maybe the >> macroassembler comments should point to the pauth_aarch64 comments. >> >> It didn't seen common in the code to describe instruction functionality, >> which is why I didn't add any. Agreed it needs something added though. > > Yeah. At the definitions of `authenticate_return_address()` et al you can say > what you expect in the normal case and what you expect when you've been > hacked, along with an overview. I realize that it was a bit tricky to make > this work with HotSpot because we're synthesizing return addresses just like > hackers do, so a comment where we're patching return addresses would be nice. > > As long as the instructions are easily findable in the docs that's good. Just to be clear: no, don't describe instructions. describe what the macros do, and when to use them. Imagine that you, the reader can't see the contents of the macro at all, just the name and the comments. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 11:44:09 GMT, Alan Hayward wrote: >> Correction: >> Using the most up to date ARM ARM G [ARM DDI 0487G.a (ID011921)] >> >> - The PAC functionality is described in ARM-ARM Section D5.1.5 >> - Overview of the PAC instructions is provided in section C3.1.10 >> - Detailed PAC instruction descriptions are provided in C6.2.208 - C6.2.212 > > I'm thinking for references to the Arm Arm to use header titles instead of > section numbers, as the titles should be more stable. > > Also probably need some description around the code in the pauth_aarch64.hpp > too. But I want to make sure I'm not duplicating comments - maybe the > macroassembler comments should point to the pauth_aarch64 comments. > > It didn't seen common in the code to describe instruction functionality, > which is why I didn't add any. Agreed it needs something added though. Yeah. At the definitions of `authenticate_return_address()` et al you can say what you expect in the normal case and what you expect when you've been hacked, along with an overview. I realize that it was a bit tricky to make this work with HotSpot because we're synthesizing return addresses just like hackers do, so a comment where we're patching return addresses would be nice. As long as the instructions are easily findable in the docs that's good. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 11:34:09 GMT, Andrew Dinn wrote: >> As far as the AArch64 docs are concerned the relevant details are provided >> in ARM-ARM D >> >> - The PAC functionality is described in ARM-ARM Section D5.1.5 >> - Overview of the PAC instructions is provided in section C3.1.9 >> - Detailed PAC instruction descriptions are provided in C6.2.195 - C6.2.199 >> >> n.b. I am specifically referring to my (possibly out of date) copy ARM-DDI >> 0487D.a (ID103018) which is the Initial v8.4 EAC release from 2018. >> >> That said, I agree that a description of how these functions use the >> underlying PAC support and what, effectively, they achieve via that usage >> would be necessary. A reference to the relevant sections of the ARM doc in >> the code would be helpful. > > Correction: > Using the most up to date ARM ARM G [ARM DDI 0487G.a (ID011921)] > > - The PAC functionality is described in ARM-ARM Section D5.1.5 > - Overview of the PAC instructions is provided in section C3.1.10 > - Detailed PAC instruction descriptions are provided in C6.2.208 - C6.2.212 I'm thinking for references to the Arm Arm to use header titles instead of section numbers, as the titles should be more stable. Also probably need some description around the code in the pauth_aarch64.hpp too. But I want to make sure I'm not duplicating comments - maybe the macroassembler comments should point to the pauth_aarch64 comments. It didn't seen common in the code to describe instruction functionality, which is why I didn't add any. Agreed it needs something added though. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Thu, 11 Nov 2021 11:19:03 GMT, Andrew Dinn wrote: >> src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp line 5185: >> >>> 5183: // ROP Protection >>> 5184: >>> 5185: void MacroAssembler::protect_return_address() { >> >> We need proper, full, detailed comments about what these functions do, with >> reference to primary AArch64 documentation. > > As far as the AArch64 docs are concerned the relevant details are provided in > ARM-ARM D > > - The PAC functionality is described in ARM-ARM Section D5.1.5 > - Overview of the PAC instructions is provided in section C3.1.9 > - Detailed PAC instruction descriptions are provided in C6.2.195 - C6.2.199 > > n.b. I am specifically referring to my (possibly out of date) copy ARM-DDI > 0487D.a (ID103018) which is the Initial v8.4 EAC release from 2018. > > That said, I agree that a description of how these functions use the > underlying PAC support and what, effectively, they achieve via that usage > would be necessary. A reference to the relevant sections of the ARM doc in > the code would be helpful. Correction: Using the most up to date ARM ARM G [ARM DDI 0487G.a (ID011921)] - The PAC functionality is described in ARM-ARM Section D5.1.5 - Overview of the PAC instructions is provided in section C3.1.10 - Detailed PAC instruction descriptions are provided in C6.2.208 - C6.2.212 - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
On Wed, 10 Nov 2021 13:22:37 GMT, Andrew Haley wrote: >> Alan Hayward has updated the pull request incrementally with one additional >> commit since the last revision: >> >> Simplify branch protection configure check > > src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp line 5185: > >> 5183: // ROP Protection >> 5184: >> 5185: void MacroAssembler::protect_return_address() { > > We need proper, full, detailed comments about what these functions do, with > reference to primary AArch64 documentation. As far as the AArch64 docs are concerned the relevant details are provided in ARM-ARM D - The PAC functionality is described in ARM-ARM Section D5.1.5 - Overview of the PAC instructions is provided in section C3.1.9 - Detailed PAC instruction descriptions are provided in C6.2.195 - C6.2.199 n.b. I am specifically referring to my (possibly out of date) copy ARM-DDI 0487D.a (ID103018) which is the Initial v8.4 EAC release from 2018. That said, I agree that a description of how these functions use the underlying PAC support and what, effectively, they achieve via that usage would be necessary. A reference to the relevant sections of the ARM doc in the code would be helpful. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64 [v2]
> 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: Simplify branch protection configure check - Changes: - all: https://git.openjdk.java.net/jdk/pull/6334/files - new: https://git.openjdk.java.net/jdk/pull/6334/files/e0e3f666..29471d30 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk=6334=01 - incr: https://webrevs.openjdk.java.net/?repo=jdk=6334=00-01 Stats: 12 lines in 1 file changed: 0 ins; 6 del; 6 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
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64
On Wed, 10 Nov 2021 14:34:18 GMT, Magnus Ihse Bursie 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. > > make/autoconf/flags-cflags.m4 line 899: > >> 897: elif test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = >> xclang; then >> 898: # Check that the compiler actually supports branch protection. >> 899: FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: >> [${BRANCH_PROTECTION_FLAG}], > > This branch misses a AC_MSG_RESULT, which prints the newline. The resulting > output will look messy. Looking at this block of code again, I've got far too many outputted lines compared to other features. Removing some means I can simplify the code too, so I'll do that. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64
On Wed, 10 Nov 2021 12:32:53 GMT, Alan Hayward 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. I am also reviewing this. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64
On Wed, 10 Nov 2021 13:34:38 GMT, Andrew Haley 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. > > src/hotspot/os_cpu/bsd_aarch64/pauth_bsd_aarch64.inline.hpp line 25: > >> 23: */ >> 24: >> 25: #ifndef OS_CPU_BSD_AARCH64_PAUTH_BSD_AARCH64_INLINE_HPP > > Are these two files different enough to separate them for BSD and Linux? My motivation was to avoid having any ifdefs - but we need one anyway for the apple ifdef. If I merged the two we would end up with just the contents of the BSD version of the file. There is also the windows version of the file, which for now has empty functions. If PAC in windows is added, that'll either use the same code or maybe Windows will provide an API (like the Apple one). Merging everything would mean windows gains the UseROPProtection check. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64
On Wed, 10 Nov 2021 12:32:53 GMT, Alan Hayward 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. Changes requested by ihse (Reviewer). make/autoconf/flags-cflags.m4 line 899: > 897: elif test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = > xclang; then > 898: # Check that the compiler actually supports branch protection. > 899: FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${BRANCH_PROTECTION_FLAG}], This branch misses a AC_MSG_RESULT, which prints the newline. The resulting output will look messy. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64
On Wed, 10 Nov 2021 12:32:53 GMT, Alan Hayward 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. src/hotspot/os_cpu/bsd_aarch64/pauth_bsd_aarch64.inline.hpp line 25: > 23: */ > 24: > 25: #ifndef OS_CPU_BSD_AARCH64_PAUTH_BSD_AARCH64_INLINE_HPP Are these two files different enough to separate them for BSD and Linux? - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64
On Wed, 10 Nov 2021 12:32:53 GMT, Alan Hayward 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. Build change looks good, but I can't comment on the code changes. - Marked as reviewed by erikj (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64
On Wed, 10 Nov 2021 13:11:21 GMT, Andrew Haley wrote: > Gosh. This is going to take some time to review, and will need at least two > reviewers. Sure. And thanks in advance. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64
On Wed, 10 Nov 2021 12:32:53 GMT, Alan Hayward 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. src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp line 5185: > 5183: // ROP Protection > 5184: > 5185: void MacroAssembler::protect_return_address() { We need proper, full, detailed comments about what these functions do, with reference to primary AArch64 documentation. - PR: https://git.openjdk.java.net/jdk/pull/6334
Re: RFR: 8264130: PAC-RET protection for Linux/AArch64
On Wed, 10 Nov 2021 12:32:53 GMT, Alan Hayward 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. Gosh. This is going to take some time to review, and will need at least two reviewers. - PR: https://git.openjdk.java.net/jdk/pull/6334
RFR: 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. - 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=6334=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