public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: Peter Zijlstra <peterz@infradead.org>
Cc: x86@kernel.org, Sami Tolvanen <samitolvanen@google.com>,
	Joao Moreira <joao@overdrivepizza.com>,
	linux-kernel@vger.kernel.org, Mark Rutland <mark.rutland@arm.com>,
	Josh Poimboeuf <jpoimboe@redhat.com>
Subject: Re: [PATCH] x86/ibt: Implement FineIBT
Date: Tue, 18 Oct 2022 11:09:13 -0700	[thread overview]
Message-ID: <202210181020.79AF7F7@keescook> (raw)
In-Reply-To: <Y06rtoE9BsERG9uv@hirez.programming.kicks-ass.net>

On Tue, Oct 18, 2022 at 03:35:50PM +0200, Peter Zijlstra wrote:
> Implement an alternative CFI scheme that merges both the fine-grained
> nature of kCFI but also takes full advantage of the coarse grained
> hardware CFI as provided by IBT.

Very nice to have!

> To contrast:
> 
>   kCFI is a pure software CFI scheme and relies on being able to read
> text -- specifically the instruction *before* the target symbol, and
> does the hash validation *before* doing the call (otherwise control
> flow is compromised already).
> 
>   FineIBT is a software and hardware hybrid scheme; by ensuring every
> branch target starts with a hash validation it is possible to place
> the hash validation after the branch. This has several advantages:
> 
>    o the (hash) load is avoided; no memop; no RX requirement.
> 
>    o IBT WAIT-FOR-ENDBR state is a speculation stop; by placing
>      the hash validation in the immediate instruction after
>      the branch target there is a minimal speculation window
>      and the whole is a viable defence against SpectreBHB.

I still think it's worth noting it does technically weaken the
"attacker-controlled executable memory content injection" attack
requirements, too. While an attacker needs to make sure they place an
ENDBR at the start of their injected code, they no longer need to also
learn and inject the CFI hash too, as the malicious code can just not
do the check at all. The difference in protection currently isn't much.

It's not a very difficult requirement to get attacker-controlled bytes
into executable memory, as there are already existing APIs that provide
this to varying degrees of reachability, utility, and discoverability --
for example, BPF JIT when constant blinding isn't enabled (the unfortunate
default). And with the hashes currently being deterministic, there's no
secret that needs to be exposed first; an attack can just calculate it.
An improvement for kCFI would be to mutate all the hashes both at build
time (perhaps using the same seed infrastructure that randstruct depends
on for sharing a seed across compilation units), and at boot time, so
an actual .text content exposure is needed to find the target hash value.

> Obviously this patch relies on kCFI (upstream), but additionally it also
> relies on the padding from the call-depth-tracking patches
> (tip/x86/core). It uses this padding to place the hash-validation while
> the call-sites are re-written to modify the indirect target to be 16
> bytes in front of the original target, thus hitting this new preamble.
> 
> Notably, there is no hardware that needs call-depth-tracking (Skylake)
> and supports IBT (Tigerlake and onwards).
> 
> Suggested-by: Joao Moreira (Intel) <joao@overdrivepizza.com>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> [...]
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -2464,13 +2464,23 @@ config FUNCTION_PADDING_BYTES
>  	default FUNCTION_PADDING_CFI if CFI_CLANG
>  	default FUNCTION_ALIGNMENT
>  
> +config CALL_PADDING
> +	def_bool n
> +	depends on CC_HAS_ENTRY_PADDING && OBJTOOL
> +	select FUNCTION_ALIGNMENT_16B
> +
> +config FINEIBT
> +	def_bool y
> +	depends on X86_KERNEL_IBT && CFI_CLANG
> +	select CALL_PADDING

To that end, can we please make this a prompted choice?

And this is a good time to ping you about this patch as well:
https://lore.kernel.org/lkml/20220902234213.3034396-1-keescook@chromium.org/

> [...]
> +#ifdef CONFIG_FINEIBT
> +/*
> + * kCFI						FineIBT
> + *
> + * __cfi_\func:					__cfi_\func:
> + *	movl   $0x12345678,%eax			     endbr64			// 4

kCFI emits endbr64 here first too ...

> + *	nop					     subl   $0x12345678,%r10d   // 7
> + *	nop					     jz     1f			// 2
> + *	nop					     ud2			// 2
> + *	nop					1:   nop			// 1
> + *	nop
> + *	nop
> + *	nop
> + *	nop
> + *	nop
> + *	nop
> + *	nop

Tangent: why are these nop instead of 0xcc? These bytes aren't executed
ever are they?

-- 
Kees Cook

  parent reply	other threads:[~2022-10-18 18:09 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-18 13:35 [PATCH] x86/ibt: Implement FineIBT Peter Zijlstra
2022-10-18 14:43 ` David Laight
2022-10-18 15:58   ` Joao Moreira
2022-10-18 17:20     ` Kees Cook
2022-10-18 20:09       ` Joao Moreira
2022-10-19  5:33         ` Kees Cook
2022-10-18 21:27     ` David Laight
2022-10-18 14:47 ` Peter Zijlstra
2022-10-18 18:09 ` Kees Cook [this message]
2022-10-18 19:56   ` Peter Zijlstra
2022-10-18 23:31     ` Josh Poimboeuf
2022-10-19  5:22       ` Kees Cook
2022-10-19 11:38       ` Peter Zijlstra
2022-10-19  5:14     ` Kees Cook
2022-10-18 19:59   ` Peter Zijlstra
2022-10-18 21:09     ` Peter Zijlstra
2022-10-19  5:05     ` Kees Cook
2022-10-19 12:03       ` Peter Zijlstra
2022-10-19 15:22         ` Sami Tolvanen
2022-10-20 11:04           ` Peter Zijlstra
2022-10-18 19:59   ` Joao Moreira
2022-10-19  5:32     ` Kees Cook
2022-10-19 19:35       ` Joao Moreira
2022-10-18 20:05   ` Peter Zijlstra
2022-10-19  5:00     ` Kees Cook
2022-10-18 20:09   ` Peter Zijlstra
2022-10-18 20:17     ` Joao Moreira
2022-10-18 20:30       ` Peter Zijlstra
2022-10-19  4:48         ` Joao Moreira
2022-10-19  5:19           ` Kees Cook
2022-10-31 19:13             ` Joao Moreira
2022-11-01 21:39               ` Kees Cook
2022-11-01 21:50                 ` Joao Moreira
2024-05-06 17:36                   ` Kees Cook
2024-05-07  1:45                     ` Joao Moreira
2022-10-19  5:18         ` Kees Cook
2022-10-19  5:16     ` Kees Cook
2022-10-20 11:05   ` Peter Zijlstra
2022-10-18 23:38 ` Josh Poimboeuf
2022-10-19  7:29   ` Peter Zijlstra
2022-10-21 23:08 ` Josh Poimboeuf
2022-10-22 15:03   ` Peter Zijlstra
2022-10-24 17:15     ` Sami Tolvanen
2022-10-24 18:38       ` Joao Moreira

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=202210181020.79AF7F7@keescook \
    --to=keescook@chromium.org \
    --cc=joao@overdrivepizza.com \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=peterz@infradead.org \
    --cc=samitolvanen@google.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox