[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] x86/cet: Use dedicated NOP4 for cf_clobber


  • To: Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
  • Date: Tue, 8 Mar 2022 14:01:26 +0000
  • Authentication-results: esa1.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Jan Beulich <JBeulich@xxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Bjoern Doebel <doebel@xxxxxxxxx>, Michael Kurth <mku@xxxxxxxxx>, Martin Pohlack <mpohlack@xxxxxxxxx>
  • Delivery-date: Tue, 08 Mar 2022 14:02:03 +0000
  • Ironport-data: A9a23:IwBB96rExgM8arH0zo4ZIsHuZ5deBmIrZRIvgKrLsJaIsI4StFCzt garIBmHPf2JZTOmftt2PIq2/E8FusfSxtQ2TFY5rC4zFCIb8JuZCYyVIHmrMnLJJKUvbq7GA +byyDXkBJppJpMJjk71atANlVEliefQAOCU5NfsYkidfyc9IMsaoU8lyrZRbrJA24DjWVvW4 YOq+aUzBXf+s9JKGjNMg068gEsHUMTa4Fv0aXRnOJinFHeH/5UkJMp3yZOZdhMUcaENdgKOf M7RzanRw4/s10xF5uVJMFrMWhZirrb6ZWBig5fNMkSoqkAqSicais7XOBeAAKv+Zvrgc91Zk b1wWZKMpQgBGb3FpcA5QkBkPGImH7Qf87LaE36mmJnGp6HGWyOEL/RGCUg3OcsT+/ptAHEI/ vsdQNwPRknd3aTsmuv9E7QywJR4RCXoFNp3VnVI5DfVF/s5B7vERL3H/4Rw1zYsnMFeW/3ZY qL1bBIxMk2YPkERaz/7Dro6jsmTpkj2KgRz6xGY+YRnvlTc0S5Yhe2F3N39JYXRGJQ9clyjj m7B8m70BjkTMdWNzjzD/n/ErurMgAvyXYsAE7v++vMCqFiLwWwXARYVfVK+qOu+jAiyVrp3O 0ESvyYjs6U23EiqVcXmGQ21pmaeuRwRUMYWFPc1gCmv4KfJ5weSBkAfUyVMLtchsaceWjgCx lKP2dTzClRSXKa9ECzHsO3O9HXrZHZTfTRqiTI4oRUtxMnqnaUXn0vzYZU7MrfshdDoKzfp6 mXfxMQhvIk7gckO3qS92FnIhTOwu5TEJjIIChXrsnGNtV0gOtP8D2C8wR2CtKsbct7FJrWUl CVcw6CjAPYy4YZhfcBnaMEEB/mX6vmMK1UwanY/TsB6p1xBF5NOFL28AQ2Sxm80aq7omhezO Sc/XD+9ArcJZBNGioctP+qM5zwCl/SIKDgcfqm8giBySpZwbhSb2ypleFSd2Wvg+GB1z/1hZ 8jLLJ31XStBYUiC8NZQb71GuVPM7npirV4/uLihl0j3uVZgTCT9pUg53KumMblisfLsTPT9+ NdDLcqaoyizo8WlChQ7BbU7dAhQRVBiXMieg5UOKoarf1o3cEl8WqS56e5wJORYc1F9y76gE oeVARQDljISRBTvdG23V5yUQO+3DcYl8yNhZnBE0JTB8yFLXLtDJZw3L/MfFYTLPsQ/pRKoZ 5Hpo/m9P8k=
  • Ironport-hdrordr: A9a23:ITb3X6MyuyoQj8BcThijsMiBIKoaSvp037By7TEJdfRUGvb4qy ncpoVi6faUskdsZJhOo6HkBEDtexzhHNtOkO8s1NSZLXbbUQmTXeVfBOLZqlWKcUCTygce79 YGT0EUMr3N5C1B/KTHCX6DYrUdKbe8npxAzt2utEuFBTsaEZ2JYm1Ce3im+2NNNXR7OaY=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

For livepatching, we need to look at a potentially clobbered function and
determine whether it used to have an ENDBR64 instruction.

Use a non-default 4-byte P6 long nop, not emitted by toolchains, and introduce
the was_endbr64() predicate.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
CC: Wei Liu <wl@xxxxxxx>
CC: Bjoern Doebel <doebel@xxxxxxxxx>
CC: Michael Kurth <mku@xxxxxxxxx>
CC: Martin Pohlack <mpohlack@xxxxxxxxx>

Bjoern: For the livepatching code, I think you want:

  if ( is_endbr64(...) || was_endbr64(...) )
      needed += ENDBR64_LEN;
---
 xen/arch/x86/alternative.c       | 10 +++++++++-
 xen/arch/x86/include/asm/endbr.h | 12 ++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/alternative.c b/xen/arch/x86/alternative.c
index d41eeef1bcaf..ffb1b1d960c8 100644
--- a/xen/arch/x86/alternative.c
+++ b/xen/arch/x86/alternative.c
@@ -362,7 +362,15 @@ static void init_or_livepatch _apply_alternatives(struct 
alt_instr *start,
             if ( !is_kernel_text(ptr) || !is_endbr64(ptr) )
                 continue;
 
-            add_nops(ptr, ENDBR64_LEN);
+            /*
+             * Can't use add_nops() here.  ENDBR64_POISON is specifically
+             * different to NOP4 so it can be spotted after the fact.
+             *
+             * All CET-capable hardware uses P6 NOPS (no need to plumb through
+             * ideal_nops), and doesn't require a branch to synchronise the
+             * instruction stream.
+             */
+            memcpy(ptr, ENDBR64_POISON, ENDBR64_LEN);
             clobbered++;
         }
 
diff --git a/xen/arch/x86/include/asm/endbr.h b/xen/arch/x86/include/asm/endbr.h
index 6090afeb0bd8..5e1e55cb467d 100644
--- a/xen/arch/x86/include/asm/endbr.h
+++ b/xen/arch/x86/include/asm/endbr.h
@@ -52,4 +52,16 @@ static inline void place_endbr64(void *ptr)
     *(uint32_t *)ptr = gen_endbr64();
 }
 
+/*
+ * After clobbering ENDBR64, we may need to confirm that the site used to
+ * contain an ENDBR64 instruction.  Use an encoding which isn't the default
+ * P6_NOP4.
+ */
+#define ENDBR64_POISON "\x66\x0f\x1f\x00" /* osp nopl (%rax) */
+
+static inline bool was_endbr64(const void *ptr)
+{
+    return *(const uint32_t *)ptr == 0x001f0f66;
+}
+
 #endif /* XEN_ASM_ENDBR_H */
-- 
2.11.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.