Add new amd64-only sysctl machdep.retpoline which says whether the cpu
authorderaadt <deraadt@openbsd.org>
Sat, 3 Feb 2024 16:21:20 +0000 (16:21 +0000)
committerderaadt <deraadt@openbsd.org>
Sat, 3 Feb 2024 16:21:20 +0000 (16:21 +0000)
requires retpoline.  If 0, we should do everything in our power to avoid
pure retpoline (replacing it with a simple thunk where possible), because
by it's nature retpoline converts an indirect-branch into a direct branch
(push to stack & ret), and therefore it is an IBT (endbr64) bypass method.
This sysctl leverages guenther's decision-making logic in the kernel, which
already uses codepatch to fix the kernel retpoline thunk.
In my opinion, the retpoline-using logic really should be flipped; ROP
execution bypassing IBT to re-enter regular control flow is more dangerous
than spectre.
ok kettenis

distrib/special/sysctl/sysctl.c
sys/arch/amd64/amd64/cpu.c
sys/arch/amd64/amd64/machdep.c
sys/arch/amd64/include/cpu.h

index e7e946c..41d1985 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sysctl.c,v 1.15 2023/05/22 09:29:54 kn Exp $  */
+/*     $OpenBSD: sysctl.c,v 1.16 2024/02/03 16:21:20 deraadt Exp $     */
 
 /*
  * Copyright (c) 2009 Theo de Raadt <deraadt@openbsd.org>
@@ -58,6 +58,10 @@ struct var vars[] = {
            { CTL_HW, HW_DISKNAMES }},
        { "hw.ncpufound", pint, 2,
            { CTL_HW, HW_NCPUFOUND }},
+#ifdef __amd64__
+       { "machdep.retpoline", pint, 2,
+           { CTL_MACHDEP, CPU_RETPOLINE }},
+#endif
 #ifdef CPU_COMPATIBLE
        { "machdep.compatible", pstring, 2,
            { CTL_MACHDEP, CPU_COMPATIBLE }},
index db06cd7..42c907d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.c,v 1.177 2023/11/22 18:50:10 bluhm Exp $ */
+/*     $OpenBSD: cpu.c,v 1.178 2024/02/03 16:21:22 deraadt Exp $       */
 /* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */
 
 /*-
@@ -163,6 +163,7 @@ int cpu_apmi_edx = 0;               /* cpuid(0x80000007).edx */
 int ecpu_ecxfeature = 0;       /* cpuid(0x80000001).ecx */
 int cpu_meltdown = 0;
 int cpu_use_xsaves = 0;
+int need_retpoline = 1;                /* most systems need retpoline */
 
 void
 replacesmap(void)
@@ -232,9 +233,11 @@ replacemeltdown(void)
        if (ibrs == 2 || (ci->ci_feature_sefflags_edx & SEFF0EDX_IBT)) {
                extern const char _jmprax, _jmpr11, _jmpr13;
                extern const short _jmprax_len, _jmpr11_len, _jmpr13_len;
+
                codepatch_replace(CPTAG_RETPOLINE_RAX, &_jmprax, _jmprax_len);
                codepatch_replace(CPTAG_RETPOLINE_R11, &_jmpr11, _jmpr11_len);
                codepatch_replace(CPTAG_RETPOLINE_R13, &_jmpr13, _jmpr13_len);
+               need_retpoline = 0;
        }
 
        if (!cpu_meltdown)
index ec472ca..9fa994b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: machdep.c,v 1.289 2024/01/19 18:38:16 kettenis Exp $  */
+/*     $OpenBSD: machdep.c,v 1.290 2024/02/03 16:21:22 deraadt Exp $   */
 /*     $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */
 
 /*-
@@ -486,6 +486,7 @@ bios_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
 
 extern int tsc_is_invariant;
 extern int amd64_has_xcrypt;
+extern int need_retpoline;
 
 const struct sysctl_bounded_args cpuctl_vars[] = {
        { CPU_LIDACTION, &lid_action, 0, 2 },
@@ -494,6 +495,7 @@ const struct sysctl_bounded_args cpuctl_vars[] = {
        { CPU_CPUFEATURE, &cpu_feature, SYSCTL_INT_READONLY },
        { CPU_XCRYPT, &amd64_has_xcrypt, SYSCTL_INT_READONLY },
        { CPU_INVARIANTTSC, &tsc_is_invariant, SYSCTL_INT_READONLY },
+       { CPU_RETPOLINE, &need_retpoline, SYSCTL_INT_READONLY },
 };
 
 /*
index 6c7ae1d..5c209b9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.h,v 1.160 2024/01/24 19:23:39 cheloha Exp $       */
+/*     $OpenBSD: cpu.h,v 1.161 2024/02/03 16:21:22 deraadt Exp $       */
 /*     $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $     */
 
 /*-
@@ -481,7 +481,8 @@ void mp_setperf_init(void);
 #define CPU_TSCFREQ            16      /* TSC frequency */
 #define CPU_INVARIANTTSC       17      /* has invariant TSC */
 #define CPU_PWRACTION          18      /* action caused by power button */
-#define CPU_MAXID              19      /* number of valid machdep ids */
+#define CPU_RETPOLINE          19      /* cpu requires retpoline pattern */
+#define CPU_MAXID              20      /* number of valid machdep ids */
 
 #define        CTL_MACHDEP_NAMES { \
        { 0, 0 }, \
@@ -503,6 +504,7 @@ void mp_setperf_init(void);
        { "tscfreq", CTLTYPE_QUAD }, \
        { "invarianttsc", CTLTYPE_INT }, \
        { "pwraction", CTLTYPE_INT }, \
+       { "retpoline", CTLTYPE_INT }, \
 }
 
 #endif /* !_MACHINE_CPU_H_ */