| <html devsite> |
| <head> |
| <title>Kernel Control Flow Integrity</title> |
| <meta name="project_path" value="/_project.yaml" /> |
| <meta name="book_path" value="/_book.yaml" /> |
| </head> |
| <body> |
| <!-- |
| Copyright 2018 The Android Open Source Project |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| //www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| <p> |
| <a href="https://clang.llvm.org/docs/ControlFlowIntegrity.html">Control flow |
| integrity</a> (CFI) is a security mechanism that disallows changes to the |
| original control flow graph of a compiled binary, making it significantly harder |
| to perform such attacks. |
| </p> |
| <p> |
| In Android 9, we enabled LLVM's implementation of CFI in more components and |
| also in the kernel. <a href="/devices/tech/debug/cfi">System CFI</a> is on by |
| default, but you need to enable kernel CFI. |
| </p> |
| <p> |
| LLVM's CFI requires compiling with <a |
| href="https://llvm.org/docs/LinkTimeOptimization.html">Link-Time Optimization |
| (LTO)</a>. LTO preserves the LLVM bitcode representation of object files until |
| link-time, which allows the compiler to better reason about what optimizations |
| can be performed. Enabling LTO reduces the size of the final binary and improves |
| performance, but increases compile time. In testing on Android, the combination |
| of LTO and CFI results in negligible overhead to code size and performance; in a |
| few cases both improved. |
| </p> |
| <p> |
| For more technical details about CFI and how other forward-control checks are |
| handled, see the <a |
| href="https://clang.llvm.org/docs/ControlFlowIntegrityDesign.html">LLVM design |
| documentation</a>. |
| </p> |
| <h2 id="implementation">Implementation</h2> |
| <p> |
| Support for kernel CFI exists in Android common kernel versions 4.9 and 4.14. If |
| your kernel is based on version 4.9 or 4.14 and you build with Clang, then you |
| can enable it. To enable kCFI, you need to copy over the relevant patches and |
| update your kernel config file. |
| </p> |
| <h3 id="copy-kcfi-patches">Copy kCFI patches</h3> |
| <p> |
| Add these changes to your kernel: |
| </p> |
| <ul> |
| <li><a |
| href="https://android-review.googlesource.com/q/topic:android-4.9-cfi">Version |
| 4.9</a></li> |
| <li><a |
| href="https://android-review.googlesource.com/q/topic:android-4.14-cfi">Version |
| 4.14</a></li> |
| </ul> |
| |
| <h3 id="enable-kcfi">Enable kCFI</h3> |
| <p> |
| After you've copied over the relevant changes, you need to enable the kCFI in |
| your kernel config file, such as |
| <code>/kernel/<var>PROJECT</var>/+/<var>BRANCH</var>/arch/arm64/configs/<var>PROJECT</var>_defconfig</code>. |
| </p> |
| <p> |
| To enable kCFI, add these lines: |
| </p> |
| |
| <pre class="prettyprint">CONFIG_LTO_CLANG=y |
| CONFIG_CFI_CLANG=y</pre> |
| |
| |
| <h3 id="troubleshooting">Troubleshooting</h3> |
| <p> |
| After enabling, work through any type mismatch errors that may exist with their |
| drivers. An indirect function call through an incompatible function pointer |
| trips CFI. When a CFI failure is detected, the kernel prints out a warning that |
| includes both the function that was called and the stacktrace that led to the |
| failure. Correct this by ensuring function pointers always have the same type as |
| the function that's called. |
| </p> |
| <p> |
| To assist in debugging CFI failures, enable <code>CONFIG_CFI_PERMISSIVE</code>, |
| which prints out a warning instead of causing a kernel panic. Permissive mode |
| must not be used in production. |
| </p> |
| |
| <h2 id="validation">Validation</h2> |
| <p> |
| Currently, there are no CTS test specifically for CFI. Instead, make sure that |
| CTS tests pass with or without CFI enabled to verify that CFI isn't impacting |
| the device. |
| </p> |
| </body> |
| </html> |