Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

cfi: add __cficanonical

With CONFIG_CFI_CLANG, the compiler replaces a function address taken
in C code with the address of a local jump table entry, which passes
runtime indirect call checks. However, the compiler won't replace
addresses taken in assembly code, which will result in a CFI failure
if we later jump to such an address in instrumented C code. The code
generated for the non-canonical jump table looks this:

<noncanonical.cfi_jt>: /* In C, &noncanonical points here */
jmp noncanonical
...
<noncanonical>: /* function body */
...

This change adds the __cficanonical attribute, which tells the
compiler to use a canonical jump table for the function instead. This
means the compiler will rename the actual function to <function>.cfi
and points the original symbol to the jump table entry instead:

<canonical>: /* jump table entry */
jmp canonical.cfi
...
<canonical.cfi>: /* function body */
...

As a result, the address taken in assembly, or other non-instrumented
code always points to the jump table and therefore, can be used for
indirect calls in instrumented code without tripping CFI checks.

Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Acked-by: Bjorn Helgaas <bhelgaas@google.com> # pci.h
Tested-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20210408182843.1754385-3-samitolvanen@google.com

authored by

Sami Tolvanen and committed by
Kees Cook
ff301ceb cf68fffb

+9 -4
+1
include/linux/compiler-clang.h
··· 63 63 #endif 64 64 65 65 #define __nocfi __attribute__((__no_sanitize__("cfi"))) 66 + #define __cficanonical __attribute__((__cfi_canonical_jump_table__))
+4
include/linux/compiler_types.h
··· 246 246 # define __nocfi 247 247 #endif 248 248 249 + #ifndef __cficanonical 250 + # define __cficanonical 251 + #endif 252 + 249 253 #ifndef asm_volatile_goto 250 254 #define asm_volatile_goto(x...) asm goto(x) 251 255 #endif
+2 -2
include/linux/init.h
··· 220 220 __initcall_name(initstub, __iid, id) 221 221 222 222 #define __define_initcall_stub(__stub, fn) \ 223 - int __init __stub(void); \ 224 - int __init __stub(void) \ 223 + int __init __cficanonical __stub(void); \ 224 + int __init __cficanonical __stub(void) \ 225 225 { \ 226 226 return fn(); \ 227 227 } \
+2 -2
include/linux/pci.h
··· 1944 1944 #ifdef CONFIG_LTO_CLANG 1945 1945 #define __DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ 1946 1946 class_shift, hook, stub) \ 1947 - void stub(struct pci_dev *dev); \ 1948 - void stub(struct pci_dev *dev) \ 1947 + void __cficanonical stub(struct pci_dev *dev); \ 1948 + void __cficanonical stub(struct pci_dev *dev) \ 1949 1949 { \ 1950 1950 hook(dev); \ 1951 1951 } \