Kirisakura custom kernel for the OnePlus 8 Pro enables Control Flow Integrity (CFI) for better security
OnePlus phones are quite popular among tinkerers, primarily because of the company’s developer-friendly attitude and of course, its painless bootloader unlocking policy. The company itself isn’t afraid to experiment and modders fully embrace the same school of thought. For example, OnePlus phones were the first few non-Pixel devices to support Energy Aware Scheduling (EAS) courtesy of XDA’s rich aftermarket development community. This is a big reason why third-party kernels are always welcome here at XDA, as they can be customized to introduce new performance features as well as security measures.
XDA Recognized Developer Freak07, better known as the maintainer of Kirisakura kernel, has now introduced a nifty security feature to the OnePlus 8 Pro through his custom kernel. The mechanism is called Control Flow Integrity (CFI), which is designed to be a runtime hardening feature, but could also be classified as a bug-finding tool – making it quite distinctive.
What is Control Flow Integrity and how is it related to hardening?
Improving security by fixing exploitable code is a very important aspect of kernel development. This, amongst others, is done regularly by the monthly Android security updates.
However, as we all know, these updates aren’t rolled out as regularly by all OEMs as we would like them to be. Additionally, the Android kernel consists of thousands and thousands of lines of code that are out of tree. Due to the complexity and size of the Android kernel, as well as the sheer diversity of the Android ecosystem, it’s difficult to fix every single exploit. Instead of fixing every single line of exploitable code, it’s beneficial to make the system more resilient against attacks by rendering the existing security bugs non-exploitable. This technique is called hardening.
That’s where Control Flow Integrity (CFI) comes into play. CFI is a security mechanism that disallows changes to the original control flow graph of a compiled binary. Due to existing memory protections that make code injection more difficult, a common attack vector is to overwrite a function pointer stored in memory.
Here is a technical explanation by Freak07 that explains a bit more about Control Flow Integrity:
Technical details about Control Flow Integrity
“The availability of a huge number of function pointers in the kernel assists the popularity of this attack pattern. Even if attackers cannot inject executable code of their own, arbitrary parts of existing kernel code can be executed to complete their exploit.
LLVM‘s CFI attempts to mitigate these attacks by restricting valid call targets and forcing a kernel panic when detecting a CFI violation. A check is added before each indirect branch to confirm that the target address points to a valid function with a correct signature. This prevents an indirect branch from jumping to an arbitrary code location and even limits the functions that can be called. An attacker will still be able to change a function pointer, if a bug allows access. But LLVM’s CFI limits 55% of indirect calls to at most 5 possible targets and 80% to at most 20 targets. In order to determine all valid call targets for each indirect branch, the compiler needs to see all of the kernel code at once.
The usage of LTO (Link Time Optimization) makes this possible. LLVM’s CFI requires the usage of LTO, where the compiler produces LLVM-specific bitcode for all C compilation units, and an LTO-aware linker uses the LLVM backend to combine the bitcode and compile it into native code.
Supplementary to permitting the usage of CFI, LTO achieves better runtime performance through whole-program analysis and cross-module optimization.
ThinLTO has nearly caught up to LTOs performance improvement. In ThinLTO mode, as with regular LTO, Clang emits LLVM bitcode after the compile phase. The ThinLTO bitcode is augmented with a compact summary of the module. During the link step, only the summaries are read and merged into a combined summary index, which includes an index of function locations for later cross-module function importing. Afterwards fast and efficient whole-program analysis is performed on the combined summary index. ThinLTO allows a multi-threaded linking process, which results in reduced compilation time.
Due to CFI interrupting program execution when hitting certain bug classes, it also classifies as a bug finding tool, as previously mentioned, when used in permissive mode. Permissive CFI will show CFI violations in the kernel log, without forcing a kernel panic. The core 4.9 (Pixel 3 generation devices) and 4.14 (Pixel 4 generation devices) kernels had several function type mismatches resulting in CFI violations, which were addressed by Google in patchsets available on the kernel/common repos.
However, due to the nature of the Android ecosystem, these mismatches are likely to be found in SoC manufacturer (in this case, Qualcomm) or OEM (OnePlus) specific code as well. Several CFI violations in Qualcomm-code distinct to the 4.19 kernel were fixed on the Kirisakura kernel for the OnePlus 8 Pro (example: 1, 2, 3).
Running the kernel in permissive CFI revealed CFI violations in code related to OnePlus drivers as well (relevant commits can be found here and here). Kirisakura kernel for the OnePlus 8 Pro runs with CFI enforced, protecting its users against this kind of code reuse attacks.”
The only Android smartphone models (that we know of) that officially support CFI are the Google Pixel 3 and Pixel 4 family. The developer tells us that his kernel is among the few custom kernels to have fully working Kernel-CFI. There is another kernel on the OnePlus 7 Pro forum that supports Kernel-CFI as well as Freak07‘s own Kirisakura kernel for the ASUS ROG Phone II, but his kernel release for the OnePlus 8 Pro is the first custom kernel for a device with Linux kernel version 4.19 to have CFI enforced.
Google strongly recommends the usage of Kernel-CFI if the device is running Android 9 Pie or higher. With OEMs sometimes being months behind the most recent security update and our phones becoming more and more connected to our lives, holding valuable private data, security features that focus on hardening the system are indeed a welcome addition to our personal smartphones. There are other kernel security features that are as important if not more important than Kernel-CFI, though, so don’t take CFI as a magic bullet that protects from all flaws.