diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2024-02-03 16:21:23 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2024-02-03 16:21:23 +0000 |
commit | a819e1a429fe10605be035d5f9fd3d98c76b2036 (patch) | |
tree | 95defb6ef98a63c88b613a8ee744f068ff761a7f /sys/arch | |
parent | 5c91698c33884b0a3f6cce362413c024017dbe9c (diff) |
Add new amd64-only sysctl machdep.retpoline which says whether the cpu
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
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/amd64/amd64/cpu.c | 5 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/machdep.c | 4 | ||||
-rw-r--r-- | sys/arch/amd64/include/cpu.h | 6 |
3 files changed, 11 insertions, 4 deletions
diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c index db06cd7d527..42c907d908a 100644 --- a/sys/arch/amd64/amd64/cpu.c +++ b/sys/arch/amd64/amd64/cpu.c @@ -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) diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index ec472ca48bd..9fa994bdceb 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -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 }, }; /* diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index 6c7ae1de4df..5c209b90aa2 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -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_ */ |