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

cfi: Add type helper macros

With CONFIG_CFI_CLANG, assembly functions called indirectly
from C code must be annotated with type identifiers to pass CFI
checking. In order to make this easier, the compiler emits a
__kcfi_typeid_<function> symbol for each address-taken function
declaration in C, which contains the expected type identifier that
we can refer to in assembly code.

Add a typed version of SYM_FUNC_START, which emits the type
identifier before the function. Architectures that support KCFI can
define their own __CFI_TYPE macro to override the default preamble
format.

As an example, for the x86_64 blowfish_dec_blk function, the
compiler emits the following type symbol:

$ readelf -sW vmlinux | grep __kcfi_typeid_blowfish_dec_blk
120204: 00000000ef478db5 0 NOTYPE WEAK DEFAULT ABS
__kcfi_typeid_blowfish_dec_blk

And SYM_TYPED_FUNC_START will generate the following preamble based
on the __CFI_TYPE definition for the architecture:

$ objdump -dr arch/x86/crypto/blowfish-x86_64-asm_64.o
...
0000000000000400 <__cfi_blowfish_dec_blk>:
...
40b: b8 00 00 00 00 mov $0x0,%eax
40c: R_X86_64_32 __kcfi_typeid_blowfish_dec_blk

0000000000000410 <blowfish_dec_blk>:
...

Note that the address of all assembly functions annotated with
SYM_TYPED_FUNC_START must be taken in C code that's linked into the
binary or the missing __kcfi_typeid_ symbol will result in a linker
error with CONFIG_CFI_CLANG. If the code that contains the indirect
call is not always compiled in, __ADDRESSABLE(functionname) can be
used to ensure that the __kcfi_typeid_ symbol is emitted.

Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Kees Cook <keescook@chromium.org>
Tested-by: Nathan Chancellor <nathan@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20220908215504.3686827-7-samitolvanen@google.com

authored by

Sami Tolvanen and committed by
Kees Cook
e84e008e 89245600

+45
+45
include/linux/cfi_types.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Clang Control Flow Integrity (CFI) type definitions. 4 + */ 5 + #ifndef _LINUX_CFI_TYPES_H 6 + #define _LINUX_CFI_TYPES_H 7 + 8 + #ifdef __ASSEMBLY__ 9 + #include <linux/linkage.h> 10 + 11 + #ifdef CONFIG_CFI_CLANG 12 + /* 13 + * Use the __kcfi_typeid_<function> type identifier symbol to 14 + * annotate indirectly called assembly functions. The compiler emits 15 + * these symbols for all address-taken function declarations in C 16 + * code. 17 + */ 18 + #ifndef __CFI_TYPE 19 + #define __CFI_TYPE(name) \ 20 + .4byte __kcfi_typeid_##name 21 + #endif 22 + 23 + #define SYM_TYPED_ENTRY(name, linkage, align...) \ 24 + linkage(name) ASM_NL \ 25 + align ASM_NL \ 26 + __CFI_TYPE(name) ASM_NL \ 27 + name: 28 + 29 + #define SYM_TYPED_START(name, linkage, align...) \ 30 + SYM_TYPED_ENTRY(name, linkage, align) 31 + 32 + #else /* CONFIG_CFI_CLANG */ 33 + 34 + #define SYM_TYPED_START(name, linkage, align...) \ 35 + SYM_START(name, linkage, align) 36 + 37 + #endif /* CONFIG_CFI_CLANG */ 38 + 39 + #ifndef SYM_TYPED_FUNC_START 40 + #define SYM_TYPED_FUNC_START(name) \ 41 + SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_A_ALIGN) 42 + #endif 43 + 44 + #endif /* __ASSEMBLY__ */ 45 + #endif /* _LINUX_CFI_TYPES_H */