diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2024-06-07 05:16:33 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2024-06-07 05:16:33 +0000 |
commit | 5c338d38019823ff68252e2cd7bed174439fad3b (patch) | |
tree | fc785b18a93ff80c5317f1fdfb8df8d7cd79249d /gnu | |
parent | db78e1ab9868ca3dd2e9eb22348709c01fb70017 (diff) |
Inside LLVM, Functions become marked with exposesReturnsTwice() if they
call a setjmp-type function (protyped with __attribute__((returns_twice)).
LLVM anticipates the longjmp type function will perform a direct branch
back (rather of a push;ret combo, almost certainly due to CET
shadow-stack coherency difficulties). Since we have CET/IBT enforced,
LLVM makes that direct branch legal by placing an endbr64 immediately
after the callq. Where I was placing the ret-clean sequence... this blows
up badly, in unhibernate / resume situations.
In the Functions marked exposesReturnsTwice(), skip doing ret-clean.
(placing the ret-clear after that endbr64 is much more difficult)
observed by mglocker, diagnosed by mlarkin, kettenis, guenther.
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/llvm/llvm/lib/Target/X86/X86RetClean.cpp | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/gnu/llvm/llvm/lib/Target/X86/X86RetClean.cpp b/gnu/llvm/llvm/lib/Target/X86/X86RetClean.cpp index 623bfede522..4d7e3e3b3cf 100644 --- a/gnu/llvm/llvm/lib/Target/X86/X86RetClean.cpp +++ b/gnu/llvm/llvm/lib/Target/X86/X86RetClean.cpp @@ -96,6 +96,10 @@ bool RetCleanPass::runOnMachineFunction(MachineFunction &MF) { bool modified = false; + // It a setjmp-like function is called by this function, we should not clean + if (MF.exposesReturnsTwice()) + return false; + for (auto &MBB : MF) { std::vector<MachineInstr*> fixups; bool foundcall = false; |