Linux kCFI/FineIBT Weaknesses Addressed By Rewriting Some Assembly In C

Written by Michael Larabel in Linux Kernel on 15 July 2023 at 06:39 AM EDT. 12 Comments
LINUX KERNEL
Ahead of the Linux 6.5-rc2 release tomorrow there was a set of x86/x86_64 kernel changes merged overnight to deal with some weaknesses in the kernel's Control Flow Integrity (kCFI) / FineIBT (Indirect Branch Tracking) code.

Going back to the Linux 6.1 days there has been the kernel Control Flow Integrity code in good shape as a replacement to prior CFI code. Since Linux 6.2 has also been FineIBT as an alternative CFI scheme that uses the compiler-provided kCFI paired with hardware Control-Flow Integrity provided by Intel's Indirect Branch Tracking.

These efforts are to thwart control-flow hijacking attacks on the kernel but recently some weaknesses were discovered in the kernel's code. Merged overnight is new code to deal with those weaknesses and part of resolving the weaknesses are rewriting some of the Assembly code into C.


Security weakness fixing by a little less hand-written Assembly in the kernel.


Intel engineer Peter Zijlstra summed up in the pull request:
The primary bug Alyssa noticed was that with FineIBT enabled function prologues have a spurious ENDBR instruction:

__cfi_foo:
endbr64
subl $hash, %r10d
jz 1f
ud2
nop
1:
foo:
endbr64 <--- *sadface*

This means that any indirect call that fails to target the __cfi symbol and instead targets (the regular old) foo+0, will succeed due to that second ENDBR.

Fixing this lead to the discovery of a single indirect call that was still doing this: ret_from_fork(), since that's an assembly stub the compiler would not generate the proper kCFI indirect call magic and it would not get patched.

Brian came up with the most comprehensive fix -- convert the thing to C with only a very thin asm wrapper. This ensures the kernel thread boostrap is a proper kCFI call.

While discussing all this, Kees noted that kCFI hashes could/should be poisoned to seal all functions whose address is never taken, further limiting the valid kCFI targets -- much like we already do for IBT.

So what was a 'simple' observation and fix cascaded into a bunch of inter-related CFI infrastructure fixes.

That code has been merged ahead of Linux 6.5-rc2 and since it provides fixes it should end up getting back-ported to the recent kernel stable series too.
Related News
About The Author
Michael Larabel

Michael Larabel is the principal author of Phoronix.com and founded the site in 2004 with a focus on enriching the Linux hardware experience. Michael has written more than 20,000 articles covering the state of Linux hardware support, Linux performance, graphics drivers, and other topics. Michael is also the lead developer of the Phoronix Test Suite, Phoromatic, and OpenBenchmarking.org automated benchmarking software. He can be followed via Twitter, LinkedIn, or contacted via MichaelLarabel.com.

Popular News This Week