Arm64: [PAC-RET] VM and coreclr support#128147
Conversation
As suggested in [comment](dotnet#125436 (comment)), this PR covers subset of changes from dotnet#125436 related to the coreclr and VM. More details on PAC and its role in software security can be found ([here](https://llsoftsec.github.io/llsoftsecbook/#sec:pointer-authentication)).
|
Tagging subscribers to this area: @agocke |
|
cc: @dotnet/arm64-contrib @a74nh @jkotas @dhartglassMSFT |
|
|
||
| // In prolog or epilog while the current frame is still being established or torn down | ||
| // retrieving correct SP is complex. We conservatively bail-out in this case. | ||
| // TODO-PAC: Explore opportunities to retrieve SP while in prolog/epilog. |
There was a problem hiding this comment.
Can this TODO be addressed? Otherwise, it is going to be a potential regression even with the PAC disabled.
I know we have discussed touching the unwinder in #110472 (comment) . The original change refactored the unwinder a lot that was a problem.
I would be ok with a small targeted change in the unwinder that just saves the signing SP if it is the best way to address this TODO.
There was a problem hiding this comment.
That makes sense. For the PAC-disabled regression specifically, would you be okay with re-introducing a VM-visible EXTERNAL_JitPacEnabled config in src/coreclr/inc/clrconfigvalues.h and using it to skip GetPacSignInfo() entirely when PAC is disabled? That would avoid the prolog/epilog bailout affecting non-PAC runs.
I completely agree the cleaner longer-term fix in unwinder that records the signing SP while processing the ARM64 unwind codes. That may avoid need of having a separate parser in GetPacSignInfo().
There was a problem hiding this comment.
I would prefer to do this properly, so that we do not have to go back and redo it.
There was a problem hiding this comment.
We could be in the prolog before the signing or in the epilog after the authentication. So, unless there is a way to reliably check we aren't in those parts, then If PAC is enabled, I think we always want to bail out if we are in the prolog or epilog. If PAC is not enabled, then being in prolog or epilog is fine.
With a TODO that we might be able to reduce the bail out window size.
Agreed with the part about getting the signing SP from the unwinder.
There was a problem hiding this comment.
We bail out for other reasons before the return address is saved to the stack memory -
runtime/src/coreclr/vm/threadsuspend.cpp
Lines 4696 to 4698 in b864585
We may want to save the signing SP in SWCB_GetExecutionState to make it easier to follow.
There was a problem hiding this comment.
I have update the patch that retrieves signing SP from the arm64 unwinder on non-Windows systems. You had highlighted that we use Windows unwinder for in-proc executions there and it doesn't support PAC. On such machines, we use GetPacSignInfo() to retrieve signing SP there. Also removed the conservative check to see if IP is in prolog or epilog as suggested.
There was a problem hiding this comment.
On such machines, we use GetPacSignInfo() to retrieve signing SP there
Does that work correctly for IPs in prologs and epilogs? I thought GetPacSignInfo is incomplete in those cases.
There was a problem hiding this comment.
Does that work correctly for IPs in prologs and epilogs? I thought GetPacSignInfo is incomplete in those cases.
I misunderstood earlier conversation, we may have missed some scenarios by skipping the IsInProlog/Epilog check. GetPacSignInfo assumes a complete unwind would give correct SP. Thus, if the thread is interrupted in prolog after LR is pushed on the stack but before all the stack manipulations, we would miscalculate the SP.
Now we are switching to the unwinder copy for both Windows and non-Windows machines. It handles partial executed prologs. I will still take a look at the corner cases where we might be interrupted on auth or ret instructions.
Do you plan to do the same on Windows as well? |
I thought that would need changes to Windows unwinder that is not part of this repo. Probably didn't understand fully what you had highlighted in earlier comments on how it can be done. |
The unwinder under src\coreclr\unwinder is a copy of the Windows unwinder. There has not been a good reason to use it on Windows so far since the copy included with the OS worked just fine. If we have a good reason to use it on Windows in some case, it should be ok to switch to using it on Windows for those cases. |
Interesting, in this case I can enable the changes for Windows too. Do we need to do anything else to force using this unwinder (in arm64/unwinder.cpp) on Windows Arm64? |
|
I expect that it may need some build changes. |
I'm trying a few things on the original/full PR. When the CI is passing, I'll move the changes over here. |
As suggested in comment, this PR covers subset of changes from #125436 related to the coreclr and VM.
More details on PAC and its role in software security can be found (here).
NOTE: This PR adds part of the changes for PAC support to simplify review process as discussed #125436 (comment). The feature is disabled by default so CI status of this PR won't reflect the impact of changes. Kindly take a look at the CI status of #125436 to ensure correctness.