From: Peter Zijlstra <peterz@infradead.org>
To: x86@kernel.org
Cc: linux-kernel@vger.kernel.org, peterz@infradead.org,
alyssa.milburn@intel.com, scott.d.constable@intel.com,
joao@overdrivepizza.com, andrew.cooper3@citrix.com,
jpoimboe@kernel.org, jose.marchesi@oracle.com,
hjl.tools@gmail.com, ndesaulniers@google.com,
samitolvanen@google.com, nathan@kernel.org, ojeda@kernel.org,
kees@kernel.org, alexei.starovoitov@gmail.com
Subject: [PATCH 11/14] llvm: kCFI pointer stuff
Date: Fri, 27 Sep 2024 21:49:07 +0200 [thread overview]
Message-ID: <20240927194925.498161564@infradead.org> (raw)
In-Reply-To: <20240927194856.096003183@infradead.org>
Quick hack to extend the Clang-kCFI function meta-data (u32 hash) with
a u8 bitmask of pointer arguments. This should really be under a new
compiler flag, dependent on both x86_64 and kCFI.
Per the comment, the bitmask represents the register based arguments
as the first 6 bits and bit 6 is used to cover all stack based
arguments. The high bit is used for invalid values.
The purpose is to put a store dependency on the set registers, thereby
blocking speculation paths that would otherwise expoit their value.
Note1:
This implementation simply sets the bit for any pointer type. A better
implementation would only set the bit for any argument that is
dereferenced in the function body.
This better implementation would also capture things like:
void foo(unsigned long addr, void *args)
{
u32 t = *(u32 *)addr;
bar(t, args);
}
Which, in contrast to the implementation below, would set bit0 while
leaving bit1 unset -- the exact opposite of this implementation.
Notably, addr *is* dereferenced, even though it is not a pointer on
entry, while args is a pointer, but is not derefereced but passed on
to bar -- if bar uses it, it gets to deal with it.
Note2:
Do we want to make this a u32 to keep room for all registers? AFAICT
the current use is only concerned with the argument registers and
those are limited to 6 for the C ABI, but custom (assembly) functions
could use things outside of that.
---
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp
index 73c745062096..42dcbc40ab4b 100644
--- a/llvm/lib/Target/X86/X86AsmPrinter.cpp
+++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp
@@ -143,11 +143,28 @@ void X86AsmPrinter::EmitKCFITypePadding(const MachineFunction &MF,
// one. Otherwise, just pad with nops. The X86::MOV32ri instruction emitted
// in X86AsmPrinter::emitKCFITypeId is 5 bytes long.
if (HasType)
- PrefixBytes += 5;
+ PrefixBytes += 7;
emitNops(offsetToAlignment(PrefixBytes, MF.getAlignment()));
}
+static uint8_t getKCFIPointerArgs(const Function &F)
+{
+ uint8_t val = 0;
+
+ if (F.isVarArg())
+ return 0x7f;
+
+ for (int i = 0; i < F.arg_size() ; i++) {
+ Argument *A = F.getArg(i);
+ Type *T = A->getType();
+ if (T->getTypeID() == Type::PointerTyID)
+ val |= 1 << std::min(i, 6);
+ }
+
+ return val;
+}
+
/// emitKCFITypeId - Emit the KCFI type information in architecture specific
/// format.
void X86AsmPrinter::emitKCFITypeId(const MachineFunction &MF) {
@@ -183,6 +200,26 @@ void X86AsmPrinter::emitKCFITypeId(const MachineFunction &MF) {
.addReg(X86::EAX)
.addImm(MaskKCFIType(Type->getZExtValue())));
+ // Extend the kCFI meta-data with a byte that has a bit set for each argument
+ // register that contains a pointer. Specifically for x86_64, which has 6
+ // argument registers:
+ //
+ // bit0 - rdi
+ // bit1 - rsi
+ // bit2 - rdx
+ // bit3 - rcx
+ // bit4 - r8
+ // bit5 - r9
+ //
+ // bit6 will denote any pointer on stack (%rsp), and all 7 bits set will
+ // indicate vararg or any other 'unknown' configuration. Leaving bit7 for
+ // error states.
+ //
+ // XXX: should be conditional on some new x86_64 specific 'bhi' argument.
+ EmitAndCountInstruction(MCInstBuilder(X86::MOV8ri)
+ .addReg(X86::AL)
+ .addImm(getKCFIPointerArgs(F)));
+
if (MAI->hasDotTypeDotSizeDirective()) {
MCSymbol *EndSym = OutContext.createTempSymbol("cfi_func_end");
OutStreamer->emitLabel(EndSym);
diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp
index cbb012161524..c0776ef78153 100644
--- a/llvm/lib/Target/X86/X86MCInstLower.cpp
+++ b/llvm/lib/Target/X86/X86MCInstLower.cpp
@@ -897,7 +897,7 @@ void X86AsmPrinter::LowerKCFI_CHECK(const MachineInstr &MI) {
.addReg(AddrReg)
.addImm(1)
.addReg(X86::NoRegister)
- .addImm(-(PrefixNops + 4))
+ .addImm(-(PrefixNops + 6))
.addReg(X86::NoRegister));
MCSymbol *Pass = OutContext.createTempSymbol();
next prev parent reply other threads:[~2024-09-27 19:51 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-27 19:48 [PATCH 00/14] x86/ibt: FineIBT-BHI Peter Zijlstra
2024-09-27 19:48 ` [PATCH 01/14] x86/cfi: Wreck things Peter Zijlstra
2024-09-27 23:15 ` Josh Poimboeuf
2024-09-28 13:31 ` Peter Zijlstra
2024-09-30 21:42 ` Josh Poimboeuf
2024-09-27 19:48 ` [PATCH 02/14] x86/boot: Mark start_secondary() with __noendbr Peter Zijlstra
2024-09-27 19:48 ` [PATCH 03/14] x86/alternative: Simplify callthunk patching Peter Zijlstra
2024-09-27 23:27 ` Josh Poimboeuf
2024-09-27 19:49 ` [PATCH 04/14] objtool/x86: Add .tail_call_sites Peter Zijlstra
2024-09-27 23:42 ` Josh Poimboeuf
2024-10-09 15:25 ` Peter Zijlstra
2024-10-10 4:55 ` Josh Poimboeuf
2024-09-27 19:49 ` [PATCH 05/14] objtool: Rename the skylake hack to --direct-call Peter Zijlstra
2024-09-27 19:49 ` [PATCH 06/14] x86/traps: Prepare for ENDBR poison UD1 usage Peter Zijlstra
2024-09-27 19:49 ` [PATCH 07/14] x86/ibt: Clean up is_endbr() Peter Zijlstra
2024-09-28 0:04 ` Josh Poimboeuf
2024-09-28 13:08 ` Peter Zijlstra
2024-09-29 17:32 ` Alexei Starovoitov
2024-09-30 8:30 ` Peter Zijlstra
2024-09-30 9:33 ` Peter Zijlstra
2024-09-30 16:43 ` Alexei Starovoitov
2024-09-30 20:58 ` Andrii Nakryiko
2024-09-27 19:49 ` [PATCH 08/14] x86/ibt: Clean up poison_endbr() Peter Zijlstra
2024-09-27 19:49 ` [PATCH 09/14] x86/ibt: Implement IBT+ Peter Zijlstra
2024-09-28 1:07 ` Josh Poimboeuf
2024-09-28 13:12 ` Peter Zijlstra
2024-09-29 17:38 ` Alexei Starovoitov
2024-09-30 8:23 ` Peter Zijlstra
2024-09-30 17:00 ` Alexei Starovoitov
2024-11-05 10:40 ` Peter Zijlstra
2024-09-27 19:49 ` [PATCH 10/14] x86/early_printk: Harden early_serial Peter Zijlstra
2024-09-27 19:49 ` Peter Zijlstra [this message]
2024-09-29 17:53 ` [PATCH 11/14] llvm: kCFI pointer stuff Alexei Starovoitov
2024-09-30 8:27 ` Peter Zijlstra
2024-09-30 16:59 ` Alexei Starovoitov
2024-10-01 10:21 ` Peter Zijlstra
2024-10-02 16:48 ` Alexei Starovoitov
2024-10-30 6:29 ` Constable, Scott D
2024-10-30 20:07 ` Constable, Scott D
2024-09-27 19:49 ` [PATCH 12/14] x86: Hacks for hacked up llvm Peter Zijlstra
2024-09-27 19:49 ` [PATCH 13/14] x86: BHI stubs Peter Zijlstra
2024-09-28 1:37 ` Josh Poimboeuf
2024-09-28 13:23 ` Peter Zijlstra
2024-09-30 21:30 ` Josh Poimboeuf
2024-09-30 21:46 ` Josh Poimboeuf
2024-09-30 22:23 ` Andrew Cooper
2024-09-30 22:38 ` Josh Poimboeuf
2024-09-30 22:52 ` Andrew Cooper
2024-10-01 11:03 ` Peter Zijlstra
2024-10-01 11:20 ` Andrew Cooper
2024-10-03 12:17 ` Peter Zijlstra
2024-10-03 13:59 ` Andrew Cooper
2024-10-14 17:50 ` Constable, Scott D
2024-10-14 21:54 ` Andrew Cooper
2024-10-21 15:06 ` Constable, Scott D
2024-10-29 5:59 ` Joao Moreira
2024-09-27 19:49 ` [PATCH 14/14] x86/fineibt: Add FineIBT+BHI mitigation Peter Zijlstra
2024-09-28 1:50 ` Josh Poimboeuf
2024-09-28 13:16 ` Peter Zijlstra
2024-10-28 5:45 ` Constable, Scott D
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240927194925.498161564@infradead.org \
--to=peterz@infradead.org \
--cc=alexei.starovoitov@gmail.com \
--cc=alyssa.milburn@intel.com \
--cc=andrew.cooper3@citrix.com \
--cc=hjl.tools@gmail.com \
--cc=joao@overdrivepizza.com \
--cc=jose.marchesi@oracle.com \
--cc=jpoimboe@kernel.org \
--cc=kees@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=ojeda@kernel.org \
--cc=samitolvanen@google.com \
--cc=scott.d.constable@intel.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®