lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  PHC 
Open Source and information security mailing list archives
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sun, 8 May 2022 01:29:13 -0700
From:   Kees Cook <>
To:     Peter Zijlstra <>
Cc:     Peter Collingbourne <>,
        Josh Poimboeuf <>,
        Joao Moreira <>,,,,,,,,,,
Subject: Re: [RFC PATCH 01/11] x86: kernel FineIBT

On Wed, May 04, 2022 at 08:16:57PM +0200, Peter Zijlstra wrote:
> 	FineIBT						kCFI
> __fineibt_\hash:
> 	xor	\hash, %r10	# 7
> 	jz	1f		# 2
> 	ud2			# 2
> 1:	ret			# 1
> 	int3			# 1
> __cfi_\sym:					__cfi_\sym:
> 							int3; int3				# 2
> 	endbr			# 4			mov	\hash, %eax			# 5
> 	call	__fineibt_\hash	# 5			int3; int3				# 2
> \sym:						\sym:
> 	...						...
> caller:						caller:
> 	movl	\hash, %r10d	# 6			cmpl	\hash, -6(%r11)			# 8
> 	sub	$9, %r11	# 4			je	1f				# 2
> 	call	*%r11		# 3			ud2					# 2
> 	.nop 4			# 4 (or fixup r11)	call	__x86_indirect_thunk_r11	# 5

This looks good!

And just to double-check my understanding here... \sym is expected to
start with endbr with IBT + kCFI?

Random extra thoughts... feel free to ignore. :) Given that both CFI
schemes depend on an attacker not being able to construct an executable
memory region that either starts with endbr (for FineIBT) or starts with
hash & 2 bytes (for kCFI), we should likely take another look at where
the kernel uses PAGE_KERNEL_EXEC.

It seems non-specialized use is entirely done via module_alloc(). Obviously
modules need to stay as-is. So we're left with other module_alloc()
callers: BPF JIT, ftrace, and kprobes.

Perhaps enabling CFI should tie bpf_jit_harden (which performs constant
blinding) to the value of bpf_jit_enable? (i.e. either use BPF VM which
reads from non-exec memory, or use BPF JIT with constant blinding.)

I *think* all the kprobes and ftrace stuff ends up using constructed
direct calls, though, yes? So if we did bounds checking, we could
"exclude" them as well as the BPF JIT. Though I'm not sure how
controllable the content written to the kprobes and ftrace regions are,

For exclusion, we could separate actual modules from the other
module_alloc() users by maybe allocating in opposite directions from the
randomized offset and check indirect calls against the kernel text bounds
and the new modules-only bounds. Sounds expensive, though. Maybe PKS,
but I can't imagine 2 MSR writes per indirect call would be fast. Hmm...

Kees Cook

Powered by blists - more mailing lists