From mboxrd@z Thu Jan 1 00:00:00 1970 From: Konstantin Ryabitsev Date: Thu, 01 Sep 2022 15:28:51 -0400 Subject: [PATCH v5 06/21] cfi: Add type helper macros MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Message-Id: <20220901-kcfi_support-v5-6-be2007d8da63@linuxfoundation.org> References: <20220901-kcfi_support-v5-0-be2007d8da63@linuxfoundation.org> In-Reply-To: <20220901-kcfi_support-v5-0-be2007d8da63@linuxfoundation.org> To: mricon@kernel.org X-Mailer: b4 0.10.0-dev-03aea X-Developer-Signature: v=1; a=openpgp-sha256; l=3735; i=konstantin@linuxfoundation.org; h=from:subject:message-id; bh=y8pn3RBVFEiRxifU93KcZ2lO1fGqJEsjM4h7lFbUHrg=; b=owGbwMvMwCW27YjM47CUmTmMp9WSGJIF2X893Wpfdauy6BdfkMiCh2/WHWF/kGu3a9/z132R276H 9yo86ChlYRDjYpAVU2Qp2xe7KajwoYdceo8pzBxWJpAhDFycAjAR4RSGf1oL3ewTr7GV3/pwdkLwhH mS57Vl1mj0pum1L+px5mu79YSR4f6f4vuNL3S3/Hnh/CyvcQrTUh752V5fD0apuyV8mHS2jh0A X-Developer-Key: i=konstantin@linuxfoundation.org; a=openpgp; fpr=DE0E66E32F1FDD0902666B96E63EDCA9329DD07E X-Endpoint-Received: by B4 Submission Endpoint for konstantin@linuxfoundation.org/default with auth_id=3 List-Id: B4 Web Endpoint Patches From: Sami Tolvanen 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_ symbol for each address-taken function declaration in C, which contains the expected type identifier that we can refer to in assembly code. Add typed versions of SYM_FUNC_START and SYM_FUNC_START_ALIAS, which emit 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 121794: ffffffffef478db5 0 NOTYPE WEAK DEFAULT ABS __kcfi_typeid_blowfish_dec_blk And SYM_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 ... 00000000000003f7 <__cfi_blowfish_dec_blk>: 3f7: cc int3 3f8: cc int3 3f9: 8b 04 25 00 00 00 00 mov 0x0,%eax 3fc: R_X86_64_32S __kcfi_typeid_blowfish_dec_blk 400: cc int3 401: cc int3 0000000000000402 : ... Note that the address of all assembly functions annotated with SYM_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 Reviewed-by: Kees Cook Tested-by: Kees Cook diff --git a/include/linux/cfi_types.h b/include/linux/cfi_types.h new file mode 100644 index 000000000000..dd16e755a197 --- /dev/null +++ b/include/linux/cfi_types.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Clang Control Flow Integrity (CFI) type definitions. + */ +#ifndef _LINUX_CFI_TYPES_H +#define _LINUX_CFI_TYPES_H + +#ifdef CONFIG_CFI_CLANG +#include + +#ifdef __ASSEMBLY__ +/* + * Use the __kcfi_typeid_ type identifier symbol to + * annotate indirectly called assembly functions. The compiler emits + * these symbols for all address-taken function declarations in C + * code. + */ +#ifndef __CFI_TYPE +#define __CFI_TYPE(name) \ + .4byte __kcfi_typeid_##name +#endif + +#define SYM_TYPED_ENTRY(name, fname, linkage, align...) \ + linkage(name) ASM_NL \ + align ASM_NL \ + __CFI_TYPE(fname) ASM_NL \ + name: + +#define __SYM_TYPED_FUNC_START_ALIAS(name, fname) \ + SYM_TYPED_ENTRY(name, fname, SYM_L_GLOBAL, SYM_A_ALIGN) + +#define __SYM_TYPED_FUNC_START(name, fname) \ + SYM_TYPED_ENTRY(name, fname, SYM_L_GLOBAL, SYM_A_ALIGN) + +#endif /* __ASSEMBLY__ */ + +#else /* CONFIG_CFI_CLANG */ + +#ifdef __ASSEMBLY__ +#define __SYM_TYPED_FUNC_START_ALIAS(name, fname) \ + SYM_FUNC_START_ALIAS(name) + +#define __SYM_TYPED_FUNC_START(name, fname) \ + SYM_FUNC_START(name) +#endif /* __ASSEMBLY__ */ + +#endif /* CONFIG_CFI_CLANG */ + +#ifdef __ASSEMBLY__ +#define SYM_TYPED_FUNC_START_ALIAS(name) \ + __SYM_TYPED_FUNC_START_ALIAS(name, name) + +#define SYM_TYPED_FUNC_START(name) \ + __SYM_TYPED_FUNC_START(name, name) +#endif /* __ASSEMBLY__ */ + +#endif /* _LINUX_CFI_TYPES_H */ -- b4 0.10.0-dev-03aea