Error if function using indirect jmp touches redzone
The indirect jmp mitigation clobbers the redzone, so verify that that is harmless.
This commit is contained in:
parent
fe8082af97
commit
130d2c7589
@ -13,7 +13,11 @@
|
||||
//
|
||||
// The runtime performance impact of this is significant!
|
||||
//
|
||||
// NOTE: This pass is incompatible with RetpolineInsertion.
|
||||
// NOTE: This pass is incompatible with RetpolineInsertion. It is also
|
||||
// incompatible with ABIs that allow red-zones, due the the
|
||||
// flags-preserving jmp mitigation clobbering 8 bytes in the red-zone.
|
||||
// Options are to disable red-zone when compiling the target binary,
|
||||
// or configure the compilers to never generate memory-indirect jmps.
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "LFenceInsertion.h"
|
||||
#include "RewriteInstance.h"
|
||||
@ -78,6 +82,11 @@ LFenceIndirectJumps("lfence-indirect-jumps",
|
||||
namespace llvm {
|
||||
namespace bolt {
|
||||
|
||||
static void report_redzone_error() {
|
||||
errs() << "BOLT-ERROR: 'Redzone access in function with indirect jmp mitigation'\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void LFenceInsertion::runOnFunctions(BinaryContext &BC) {
|
||||
|
||||
if (!opts::InsertLFences)
|
||||
@ -96,6 +105,8 @@ void LFenceInsertion::runOnFunctions(BinaryContext &BC) {
|
||||
uint32_t LFencedIndirectJmps = 0;
|
||||
for (auto &It : BC.getBinaryFunctions()) {
|
||||
auto &Function = It.second;
|
||||
bool MemIndirectJmp = false;
|
||||
bool Redzone = false;
|
||||
|
||||
// For performance reasons, we may want to skip some functions and
|
||||
// manually add lfences to them only where absolutely needed.
|
||||
@ -107,6 +118,19 @@ void LFenceInsertion::runOnFunctions(BinaryContext &BC) {
|
||||
for (auto It = BB.begin(); It != BB.end(); ++It) {
|
||||
auto &Inst = *It;
|
||||
|
||||
if (MIB.isActualLoad(Inst) && MIB.isBranchOnMem(Inst)) {
|
||||
IndirectBranchInfo BrInfo(Inst, MIB);
|
||||
const auto &MemRef = BrInfo.Memory;
|
||||
|
||||
if (MemRef.BaseRegNum == MIB.getStackPointer() &&
|
||||
MemRef.DispValue < 0) {
|
||||
if (MemIndirectJmp) {
|
||||
report_redzone_error();
|
||||
}
|
||||
Redzone = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts::LFenceConditionalBranches &&
|
||||
MIB.isConditionalBranch(Inst)) {
|
||||
// Inserts a lfence before every conditional branch.
|
||||
@ -175,11 +199,10 @@ void LFenceInsertion::runOnFunctions(BinaryContext &BC) {
|
||||
// popq %rdi
|
||||
// lfence
|
||||
// pushq (%rsi)
|
||||
// lfence
|
||||
// lfence //XXX Not needed, according to Intel?
|
||||
// shlq $0, (%rsp)
|
||||
// lfence
|
||||
// retq
|
||||
|
||||
IndirectBranchInfo BrInfo(Inst, MIB);
|
||||
const auto &MemRef = BrInfo.Memory;
|
||||
auto *Ctx = BC.Ctx.get();
|
||||
@ -250,10 +273,18 @@ void LFenceInsertion::runOnFunctions(BinaryContext &BC) {
|
||||
// jmpq *(%rsi)
|
||||
// gets rewritten to:
|
||||
// pushq (%rsi)
|
||||
// lfence
|
||||
// lfence //XXX Not needed, according to Intel?
|
||||
// shlq $0, (%rsp)
|
||||
// lfence
|
||||
// retq
|
||||
|
||||
// Since this mitigation clobbers the redzone, we need to make
|
||||
// sure that this function never uses it.
|
||||
if (Redzone) {
|
||||
report_redzone_error();
|
||||
}
|
||||
MemIndirectJmp = true;
|
||||
|
||||
IndirectBranchInfo BrInfo(Inst, MIB);
|
||||
const auto &MemRef = BrInfo.Memory;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user