| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ |
|---|
| 2 | +/* |
|---|
| 3 | + * Clang Control Flow Integrity (CFI) support. |
|---|
| 4 | + * |
|---|
| 5 | + * Copyright (C) 2019 Google LLC |
|---|
| 6 | + */ |
|---|
| 1 | 7 | #ifndef _LINUX_CFI_H |
|---|
| 2 | 8 | #define _LINUX_CFI_H |
|---|
| 3 | 9 | |
|---|
| 4 | | -#include <linux/stringify.h> |
|---|
| 5 | | - |
|---|
| 6 | 10 | #ifdef CONFIG_CFI_CLANG |
|---|
| 7 | | -#ifdef CONFIG_MODULES |
|---|
| 8 | | - |
|---|
| 9 | | -typedef void (*cfi_check_fn)(uint64_t, void *, void *); |
|---|
| 11 | +typedef void (*cfi_check_fn)(uint64_t id, void *ptr, void *diag); |
|---|
| 10 | 12 | |
|---|
| 11 | 13 | /* Compiler-generated function in each module, and the kernel */ |
|---|
| 12 | | -#define CFI_CHECK_FN __cfi_check |
|---|
| 13 | | -#define CFI_CHECK_FN_NAME __stringify(CFI_CHECK_FN) |
|---|
| 14 | +extern void __cfi_check(uint64_t id, void *ptr, void *diag); |
|---|
| 14 | 15 | |
|---|
| 15 | | -extern void CFI_CHECK_FN(uint64_t, void *, void *); |
|---|
| 16 | +/* |
|---|
| 17 | + * Force the compiler to generate a CFI jump table entry for a function |
|---|
| 18 | + * and store the jump table address to __cfi_jt_<function>. |
|---|
| 19 | + */ |
|---|
| 20 | +#define __CFI_ADDRESSABLE(fn) \ |
|---|
| 21 | + const void* __cfi_jt_ ## fn __visible = (void *)&fn; |
|---|
| 16 | 22 | |
|---|
| 17 | 23 | #ifdef CONFIG_CFI_CLANG_SHADOW |
|---|
| 18 | | -extern void cfi_module_add(struct module *mod, unsigned long min_addr, |
|---|
| 19 | | - unsigned long max_addr); |
|---|
| 20 | 24 | |
|---|
| 21 | | -extern void cfi_module_remove(struct module *mod, unsigned long min_addr, |
|---|
| 22 | | - unsigned long max_addr); |
|---|
| 25 | +extern void cfi_module_add(struct module *mod, unsigned long base_addr); |
|---|
| 26 | +extern void cfi_module_remove(struct module *mod, unsigned long base_addr); |
|---|
| 27 | + |
|---|
| 23 | 28 | #else |
|---|
| 24 | | -static inline void cfi_module_add(struct module *mod, unsigned long min_addr, |
|---|
| 25 | | - unsigned long max_addr) |
|---|
| 26 | | -{ |
|---|
| 27 | | -} |
|---|
| 28 | 29 | |
|---|
| 29 | | -static inline void cfi_module_remove(struct module *mod, unsigned long min_addr, |
|---|
| 30 | | - unsigned long max_addr) |
|---|
| 31 | | -{ |
|---|
| 32 | | -} |
|---|
| 30 | +static inline void cfi_module_add(struct module *mod, unsigned long base_addr) {} |
|---|
| 31 | +static inline void cfi_module_remove(struct module *mod, unsigned long base_addr) {} |
|---|
| 32 | + |
|---|
| 33 | 33 | #endif /* CONFIG_CFI_CLANG_SHADOW */ |
|---|
| 34 | 34 | |
|---|
| 35 | | -#endif /* CONFIG_MODULES */ |
|---|
| 35 | +#else /* !CONFIG_CFI_CLANG */ |
|---|
| 36 | + |
|---|
| 37 | +#define __CFI_ADDRESSABLE(fn) |
|---|
| 38 | + |
|---|
| 36 | 39 | #endif /* CONFIG_CFI_CLANG */ |
|---|
| 37 | 40 | |
|---|
| 38 | 41 | #endif /* _LINUX_CFI_H */ |
|---|