[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <202205141501.92A22264B4@keescook>
Date: Sat, 14 May 2022 15:02:56 -0700
From: Kees Cook <keescook@...omium.org>
To: Sami Tolvanen <samitolvanen@...gle.com>
Cc: linux-kernel@...r.kernel.org, Josh Poimboeuf <jpoimboe@...hat.com>,
Peter Zijlstra <peterz@...radead.org>, x86@...nel.org,
Catalin Marinas <catalin.marinas@....com>,
Will Deacon <will@...nel.org>,
Mark Rutland <mark.rutland@....com>,
Nathan Chancellor <nathan@...nel.org>,
Nick Desaulniers <ndesaulniers@...gle.com>,
Joao Moreira <joao@...rdrivepizza.com>,
Sedat Dilek <sedat.dilek@...il.com>,
Steven Rostedt <rostedt@...dmis.org>,
linux-hardening@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org, llvm@...ts.linux.dev
Subject: Re: [RFC PATCH v2 20/21] x86: Add support for CONFIG_CFI_CLANG
On Fri, May 13, 2022 at 01:21:58PM -0700, Sami Tolvanen wrote:
> With CONFIG_CFI_CLANG, the compiler injects a type preamble
> immediately before each function and a check to validate the target
> function type before indirect calls:
>
> ; type preamble
> __cfi_function:
> int3
> int3
> mov <id>, %eax
> int3
> int3
> function:
> ...
> ; indirect call check
> cmpl <id>, -6(%r11)
> je .Ltmp1
> ud2
> .Ltmp1:
> call __x86_indirect_thunk_r11
>
> Define the __CFI_TYPE helper macro for manual type annotations in
> assembly code, add error handling for the CFI ud2 traps, and allow
> CONFIG_CFI_CLANG to be selected on x86_64.
>
> Signed-off-by: Sami Tolvanen <samitolvanen@...gle.com>
> ---
> arch/x86/Kconfig | 2 ++
> arch/x86/include/asm/linkage.h | 12 +++++++
> arch/x86/kernel/traps.c | 60 +++++++++++++++++++++++++++++++++-
> 3 files changed, 73 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 4bed3abf444d..2e73d0792d48 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -108,6 +108,8 @@ config X86
> select ARCH_SUPPORTS_PAGE_TABLE_CHECK if X86_64
> select ARCH_SUPPORTS_NUMA_BALANCING if X86_64
> select ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP if NR_CPUS <= 4096
> + select ARCH_SUPPORTS_CFI_CLANG if X86_64
> + select ARCH_USES_CFI_TRAPS if X86_64 && CFI_CLANG
> select ARCH_SUPPORTS_LTO_CLANG
> select ARCH_SUPPORTS_LTO_CLANG_THIN
> select ARCH_USE_BUILTIN_BSWAP
> diff --git a/arch/x86/include/asm/linkage.h b/arch/x86/include/asm/linkage.h
> index 85865f1645bd..0ee4a0af3974 100644
> --- a/arch/x86/include/asm/linkage.h
> +++ b/arch/x86/include/asm/linkage.h
> @@ -25,6 +25,18 @@
> #define RET ret
> #endif
>
> +#ifdef CONFIG_CFI_CLANG
> +#define __CFI_TYPE(name) \
> + .fill 7, 1, 0xCC ASM_NL \
> + SYM_START(__cfi_##name, SYM_L_LOCAL, SYM_A_NONE) \
> + int3 ASM_NL \
> + int3 ASM_NL \
> + mov __kcfi_typeid_##name, %eax ASM_NL \
> + int3 ASM_NL \
> + int3 ASM_NL \
> + SYM_FUNC_END(__cfi_##name)
> +#endif
> +
> #else /* __ASSEMBLY__ */
>
> #ifdef CONFIG_SLS
> diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
> index 1563fb995005..320e257eb4be 100644
> --- a/arch/x86/kernel/traps.c
> +++ b/arch/x86/kernel/traps.c
> @@ -40,6 +40,7 @@
> #include <linux/hardirq.h>
> #include <linux/atomic.h>
> #include <linux/ioasid.h>
> +#include <linux/cfi.h>
>
> #include <asm/stacktrace.h>
> #include <asm/processor.h>
> @@ -295,6 +296,62 @@ static inline void handle_invalid_op(struct pt_regs *regs)
> ILL_ILLOPN, error_get_trap_addr(regs));
> }
>
> +#ifdef CONFIG_CFI_CLANG
> +static void decode_cfi_insn(struct pt_regs *regs, unsigned long *target,
> + unsigned long *type)
> +{
> + char buffer[MAX_INSN_SIZE];
> + struct insn insn;
> + int offset;
> +
> + *target = *type = 0;
Should report_cfi_failure() have some additional hinting for the case
where target/type are zero? Like, "hey, got an inexplicable CFI failure
here, but preamble decode failed. Yikes!"
Reviewed-by: Kees Cook <keescook@...omium.org>
--
Kees Cook
Powered by blists - more mailing lists