From c066606085856e2b354717ecffc5d2d878dff9b9 Mon Sep 17 00:00:00 2001 From: deraadt Date: Fri, 7 Jun 2024 05:16:32 +0000 Subject: [PATCH] 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. --- gnu/llvm/llvm/lib/Target/X86/X86RetClean.cpp | 4 ++++ 1 file changed, 4 insertions(+) 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 fixups; bool foundcall = false; -- 2.20.1