This is an archive of the discontinued LLVM Phabricator instance.

[lsan] Fix stack buffer overwrite in SuspendedThreadsListMac::GetRegistersAndSP
ClosedPublic

Authored by kubamracek on Nov 2 2022, 2:51 PM.

Details

Summary

The call to the thread_get_state syscall (that fetches the register values for a thread) on arm64 is mistakenly claiming that the buffer to receive the register state is larger that its actual size on the stack -- the struct on the stack is arm_thread_state64_t, but the MACHINE_THREAD_STATE + MACHINE_THREAD_STATE_COUNT refer to the "unified arm state" struct (which is larger).

Fixes https://github.com/llvm/llvm-project/issues/58503.

Diff Detail

Event Timeline

kubamracek created this revision.Nov 2 2022, 2:51 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 2 2022, 2:51 PM
kubamracek requested review of this revision.Nov 2 2022, 2:51 PM
Herald added a subscriber: Restricted Project. · View Herald TranscriptNov 2 2022, 2:51 PM
vitalybuka accepted this revision.Nov 2 2022, 2:59 PM
This revision is now accepted and ready to land.Nov 2 2022, 2:59 PM

BTW. Repro is very trivial, would you like to add a regression test?

BTW. Repro is very trivial, would you like to add a regression test?

Do you have a specific test/approach in mind? I think this is well covered by existing tests, basically all LSan tests exercise this codepath. But the bug (the hang) only triggers on arm64 and I bet the reason why CI and buildbots didn't discover this is that they don't actually run on Apple Silicon Mac hardware.

BTW. Repro is very trivial, would you like to add a regression test?

Do you have a specific test/approach in mind? I think this is well covered by existing tests, basically all LSan tests exercise this codepath. But the bug (the hang) only triggers on arm64 and I bet the reason why CI and buildbots didn't discover this is that they don't actually run on Apple Silicon Mac hardware.

You are right. LGTM without the test.

Added a minor comment below. Apart from that looks good to me

compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cpp
152–153

I will just suggest using the corresponding macros for reg count, e.g. ARM_THREAD_STATE64_COUNT etc. from the headers rather the inlining the calculation. Apart from that looks good to me.

kubamracek added inline comments.Nov 11 2022, 12:42 PM
compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cpp
152–153

I think I'm slightly against that (I considered it initially) because this is exactly what caused the bug in the first place (!) and triggered a stack smasher (!!!) with very non-obvious consequences. The reg_count variable is telling thread_get_state how large the buffer is that it can write to... and I'd say that the most correct and most obvious way of getting that right is by actually using sizeof on the actual stack variable that holds the buffer.

usama54321 added inline comments.Nov 11 2022, 2:31 PM
compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cpp
152–153

In that case, it is fine. I suggested that because I have been recently fixing bugs in ubsan where some definitions were out of sync from the headers. However, that seems less likely here.

usama54321 accepted this revision.Nov 11 2022, 2:34 PM
thetruestblue accepted this revision.Nov 11 2022, 9:15 PM

LGTM -- fixes the arm64 hang I've been running into.

This revision was landed with ongoing or failed builds.Nov 12 2022, 10:18 AM
This revision was automatically updated to reflect the committed changes.