Print this page
11787 Kernel needs to be built with retpolines
11788 Kernel needs to generally use RSB stuffing
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: John Levon <john.levon@joyent.com>

*** 22,36 **** /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _IA32_SYS_ASM_LINKAGE_H #define _IA32_SYS_ASM_LINKAGE_H - #pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/stack.h> #include <sys/trap.h> #ifdef __cplusplus extern "C" { --- 22,38 ---- /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ + /* + * Copyright 2019 Joyent, Inc. + */ + #ifndef _IA32_SYS_ASM_LINKAGE_H #define _IA32_SYS_ASM_LINKAGE_H #include <sys/stack.h> #include <sys/trap.h> #ifdef __cplusplus extern "C" {
*** 298,307 **** --- 300,349 ---- #define NWORD long #endif /* __i386 */ + /* + * These macros should be used when making indirect calls in the kernel. They + * will perform a jump or call to the corresponding register in a way that knows + * about retpolines and handles whether such mitigations are enabled or not. + * + * INDIRECT_JMP_REG will jump to named register. INDIRECT_CALL_REG will instead + * do a call. These macros cannot be used to dereference a register. For + * example, if you need to do something that looks like the following: + * + * call *24(%rdi) + * jmp *(%r15) + * + * You must instead first do a movq into the corresponding location. You need to + * be careful to make sure that the register that its loaded into is safe to + * use. Often that register may be saved or used elsewhere so it may not be safe + * to clobber the value. Usually, loading into %rax would be safe. These would + * turn into something like: + * + * movq 24(%rdi), %rdi; INDIRECT_CALL_REG(rdi) + * movq (%r15), %r15; INDIRECT_JMP_REG(r15) + * + * If you are trying to call a global function, then use the following pattern + * (substituting the register in question): + * + * leaq my_favorite_function(%rip), %rax + * INDIRECT_CALL_REG(rax) + * + * If you instead have a function pointer (say gethrtimef for example), then you + * need to do: + * + * movq my_favorite_function_pointer(%rip), %rax + * INDIRECT_CALL_REG(rax) + */ + + /* CSTYLED */ + #define INDIRECT_JMP_REG(reg) jmp __x86_indirect_thunk_/**/reg; + + /* CSTYLED */ + #define INDIRECT_CALL_REG(reg) call __x86_indirect_thunk_/**/reg; + #endif /* _ASM */ #ifdef __cplusplus } #endif