Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use QueueUserAPC2 for EE suspension on CoreCLR win-arm64. #101891

Merged
merged 11 commits into from
May 8, 2024

Conversation

VSadov
Copy link
Member

@VSadov VSadov commented May 5, 2024

EE Suspension scheme that uses signal-like APIs scales better on manycore machines and should be used when available.

NativeAOT uses QueueUserAPC2 on win-arm64 since 8.0

Re: #80087

Copy link
Contributor

Tagging subscribers to this area: @mangod9
See info in area-owners.md if you want to be subscribed.

@VSadov
Copy link
Member Author

VSadov commented May 6, 2024

CC @jkotas - a simple change. Kind of a follow up to #99076

@VSadov VSadov requested a review from jkotas May 6, 2024 16:45
@jkotas
Copy link
Member

jkotas commented May 6, 2024

Do we also need to enable the code around GetReturnAddressHijackTarget and STATUS_RETURN_ADDRESS_HIJACK_ATTEMPT to make return address hijacking work well with control flow guard / shadow stacks?

It sounds like we missed porting the return address hijacking part of the CET work to native AOT. Do you recall whether we have tested native AOT with CET enabled?

@VSadov
Copy link
Member Author

VSadov commented May 6, 2024

Supporting CET in NativeAOT was always something that we would want to do eventually, but we never got to actually doing it.

Using APC2 for suspension was mostly because in NativeAOT architecture it was easy to do and there are performance advantages. It was not a part of CET package.

@jkotas
Copy link
Member

jkotas commented May 7, 2024

Do you plan to enable GetReturnAddressHijackTarget paths in this PR too, or is it left for a different one?

@VSadov
Copy link
Member Author

VSadov commented May 7, 2024

Do you plan to enable GetReturnAddressHijackTarget paths in this PR too, or is it left for a different one?

Implementing that would mean also implementing and testing the STATUS_RETURN_ADDRESS_HIJACK_ATTEMPT support for arm64. From looking at Windows side of things, it appears that nothing of that is implemented and RtlGetReturnAddressHijackTarget would just return NULL, so nothing would be testable.

I think I will "implement" GetReturnAddressHijackTarget for arm64 just enough to have fewer #ifdefs, but leave STATUS_RETURN_ADDRESS_HIJACK_ATTEMPT for the future time when we can test it.

@@ -4747,7 +4747,7 @@ void Thread::HijackThread(ReturnKind returnKind, ExecutionState *esb)

VOID *pvHijackAddr = reinterpret_cast<VOID *>(OnHijackTripThread);

#if defined(TARGET_WINDOWS) && defined(TARGET_AMD64)
#if defined(TARGET_WINDOWS)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Update comment on #endif

#elif defined(TARGET_WINDOWS) && defined(TARGET_AMD64)
// Only versions of Windows that have the special user mode APC have a correct implementation of the return address hijack handling
if (Thread::UseSpecialUserModeApc())
#elif defined(TARGET_WINDOWS)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dtto

VSadov and others added 2 commits May 7, 2024 14:50
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
// Only versions of Windows that have the special user mode APC have a correct implementation of the return address hijack handling
if (Thread::UseSpecialUserModeApc())
#elif defined(TARGET_WINDOWS)
if (Thread::AreCetShadowStacksEnabled())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you change this condition like this, the conditions in STATUS_RETURN_ADDRESS_HIJACK_ATTEMPT handling can be simplified to if (Thread::AreCetShadowStacksEnabled() && (pExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_RETURN_ADDRESS_HIJACK_ATTEMPT))

Copy link
Member Author

@VSadov VSadov May 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this and decided not to tie one condition to another.
STATUS_RETURN_ADDRESS_HIJACK_ATTEMPT path can work if CET is not enabled. We had it that way, although it was a bit wasteful - lots of exceptions thrown/caught.

I can see such scenario enabled though, at least for test purposes. I did that a few times by turning the condition here into if(true), so I was hesitant to condition the ability to handle STATUS_RETURN_ADDRESS_HIJACK_ATTEMPT on enablement of shadow stacks.

Perf savings from not looking at ExceptionCode are probably very minor.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we condition ability to handle STATUS_RETURN_ADDRESS_HIJACK_ATTEMPT on enablement of CET, then some code inside support for STATUS_RETURN_ADDRESS_HIJACK_ATTEMPT can also be simplified. - the places under

if (areCetShadowStacksEnabled)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, the handling of STATUS_RETURN_ADDRESS_HIJACK_ATTEMPT can stay as is then.

I have noticed that there is a bug in STATUS_RETURN_ADDRESS_HIJACK_ATTEMPT handling that will show up when multiple runtimes in the process use it. We should bail if the thread is null or if we are not in cooperative mode. We know that it is some other code triggering STATUS_RETURN_ADDRESS_HIJACK_ATTEMPT in that case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should bail if the thread is null or if we are not in cooperative mode.

I think that would still allow for scenario where we try handling somebody's else hijacked method.
We may need to check for the code ownership - like have IsManaged() somewhere.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although we would not be cooperative if running somebody else's code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although we would not be cooperative if running somebody else's code.

Right

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have pushed a few commits with cosmetic cleanup.

Thank you!

@VSadov
Copy link
Member Author

VSadov commented May 8, 2024

Thanks!!

@VSadov VSadov merged commit 5f02413 into dotnet:main May 8, 2024
89 checks passed
@VSadov VSadov deleted the apc2arm branch May 8, 2024 14:39
@VSadov VSadov restored the apc2arm branch May 8, 2024 15:51
michaelgsharp pushed a commit to michaelgsharp/runtime that referenced this pull request May 9, 2024
)

* use APC2 on arm64

* Made AreCetShadowStacksEnabled available on arm64, with trivial implementation for now.

* Enabled querying for GetReturnAddressHijackTarget  on arm64

* Apply suggestions from code review

Co-authored-by: Jan Kotas <jkotas@microsoft.com>

* updated #endif

* not handling STATUS_RETURN_ADDRESS_HIJACK_ATTEMPT if not in coop mode.

* Assert that a hijack target is provided when CET is enabled

* Nit

* AreCetShadowStacksEnabled -> AreShadowStacksEnabled

* Update src/coreclr/vm/threadsuspend.cpp

* Update src/coreclr/vm/threads.cpp

---------

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Ruihan-Yin pushed a commit to Ruihan-Yin/runtime that referenced this pull request May 30, 2024
)

* use APC2 on arm64

* Made AreCetShadowStacksEnabled available on arm64, with trivial implementation for now.

* Enabled querying for GetReturnAddressHijackTarget  on arm64

* Apply suggestions from code review

Co-authored-by: Jan Kotas <jkotas@microsoft.com>

* updated #endif

* not handling STATUS_RETURN_ADDRESS_HIJACK_ATTEMPT if not in coop mode.

* Assert that a hijack target is provided when CET is enabled

* Nit

* AreCetShadowStacksEnabled -> AreShadowStacksEnabled

* Update src/coreclr/vm/threadsuspend.cpp

* Update src/coreclr/vm/threads.cpp

---------

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
@github-actions github-actions bot locked and limited conversation to collaborators Jun 8, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants