8387792: Enable PAC-RET for VM code on Windows/ARM64#31795
Conversation
This patch adds MSVC's "/guard:signret" flag to the C/C++ compilation
flags so that the VM code includes signing and authentication
instructions to ensure that the return address is not tampered by any
callee. Specifically, MSVC chooses signing using the B key, so every
non-leaf function starts with the `pacibsp` instruction (for signining
the return address) and ends with the `autibsp` instruction (for
authenticating the return address). Both `pacibsp` and `autibsp`
instructions are in the NOP space, so older AArch64 processors that do
not support these instructions shouldn't be impacted by these
instructions.
As a matter of slight detail, this patch adds the "/guard:signret" flag
only when the OpenJDK build is passed the "--enable-branch-protection"
flag, which is off by default. Consequently, this change will not
impact ordinary builds of OpenJDK.
I've validated this patch by running the test/jdk:tier{1,2,3},
test/hotspot/jtreg:tier{1,2,3}, test/langtools:tier{1,2,3}, and
test/lib-test:tier1 tests with branch protection enabled. This patch
does not introduce any new failures.
|
👋 Welcome back arane! A progress list of the required criteria for merging this PR into |
|
❗ This change is not yet ready to be integrated. |
|
@raneashay The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
dholmes-ora
left a comment
There was a problem hiding this comment.
Seems reasonable. I have a couple of queries, but the approval needs to come from @erikj79 .
| BRANCH_PROTECTION_FLAG="-mbranch-protection=standard" | ||
| FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$BRANCH_PROTECTION_FLAG], | ||
| IF_TRUE: [BRANCH_PROTECTION_AVAILABLE=true]) | ||
| elif test "x$TOOLCHAIN_TYPE" = xmicrosoft && test "x$OPENJDK_TARGET_OS" = xwindows; then |
There was a problem hiding this comment.
Is it possible for the toolchain type to be "microsoft" when the target OS is not "windows"??
Related: the docs say this is/was Linux only, but the preceding logic does not check the OS for gcc/clang. ??
| if test "x$BRANCH_PROTECTION_ENABLED" = "xtrue" && \ | ||
| # MSVC's assembler does not support branch protection flags. | ||
| test "x$TOOLCHAIN_TYPE" != xmicrosoft; then | ||
| $2JVM_ASFLAGS="${$2JVM_ASFLAGS} $BRANCH_PROTECTION_FLAG" |
There was a problem hiding this comment.
I wonder if it would be cleaner to separate the BP compiler flag from the BP assembler flag? (E.g. we would define BRANCH_PROTECTION_CFLAG and BRANCH_PROTECTION_ASFLAG separately and so avoid repeating platform/toolchain checks.)
|
Thanks David for taking a look! I will incorporate the suggestions soon. Just as a heads up, I discovered that this patch breaks the Sorry about any confusion that this causes, but I wanted to let you know there's an additional (small) change required to this patch. I'll post an update after I run through all tests again. |
|
@raneashay |
|
The total number of required reviews for this PR has been set to 2 based on the presence of this label: |
|
Fixed the stack walking issue using the Also merged the master branch to pull an unrelated test fix. |
This file is only built for Windows/ARM64, so we don't need to check of `_M_ARM64`.
|
Thanks for the updates. Can't comment on the Aarch64 specifics but I will put this through our build system just as a sanity check. |
|
Sanity build check was fine. |
|
Regarding the test you've done, IIUC, you built one JDK with Note that as listed in https://bugs.openjdk.org/browse/JDK-8388072, I found ~500 jtreg failures on Linux/AArch64(i.e. Neoverse-V1 cpu). I was wondering did you find any jtreg failure on Win/AArch64 side? Thanks |
|
Hi @shqking, thanks much for running the tests with "-XX:UseBranchProtection". I was under the (now mistaken) assumption that because this patch doesn't change the runtime CPU detection code for the CPU_PACA feature, the "-XX:UseBranchProtection" flag would have no effect, so I was running tests without passing "JTREG=VM_OPTIONS=-XX:UseBranchProtection=standard". I was able to reproduce the assertion failure. The problem is that the LHS of the assertion ( Since you have a JBS issue for this, would you like to add it to your fix? If not, I'm happy to roll it into this patch. In the meantime, I'll go run all of my tests again with "-XX:UseBranchProtection=standard". |
|
@raneashay Thanks for your reply. Yes, adding ContinuationHelper::return_address_at() should resolve the assertion failure. Based on my local testing, there are several call sites where this helper is required, and I currently have a WIP fix addressing them.
Either approach works for me. That said, I suggest keeping this PR narrowly scoped—focused on the build system and C runtime changes rather than Java code—and handling the assertion fixes separately under my JBS issue. WDYT? |
This patch adds MSVC's "/guard:signret" flag to the C/C++ compilation
flags so that the VM code includes signing and authentication
instructions to ensure that the return address is not tampered by any
callee. Specifically, MSVC chooses signing using the B key, so every
non-leaf function starts with the
pacibspinstruction (for signiningthe return address) and ends with the
autibspinstruction (forauthenticating the return address). Both
pacibspandautibspinstructions are in the NOP space, so older AArch64 processors that do
not support these instructions shouldn't be impacted by these
instructions.
As a matter of slight detail, this patch adds the "/guard:signret" flag
only when the OpenJDK build is passed the "--enable-branch-protection"
flag, which is off by default. Consequently, this change will not
impact ordinary builds of OpenJDK.
I've validated this patch by running the test/jdk:tier{1,2,3},
test/hotspot/jtreg:tier{1,2,3}, test/langtools:tier{1,2,3}, and
test/lib-test:tier1 tests with branch protection enabled. This patch
does not introduce any new failures.
Progress
Issue
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/31795/head:pull/31795$ git checkout pull/31795Update a local copy of the PR:
$ git checkout pull/31795$ git pull https://git.openjdk.org/jdk.git pull/31795/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 31795View PR using the GUI difftool:
$ git pr show -t 31795Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/31795.diff
Using Webrev
Link to Webrev Comment