[PATCH v7 00/11] CFI for ARM32 using LLVM

Sami Tolvanen samitolvanen at google.com
Mon Apr 22 14:50:18 PDT 2024


On Sun, Apr 21, 2024 at 11:28 AM Linus Walleij <linus.walleij at linaro.org> wrote:
>
> This is a first patch set to support CLANG CFI (Control Flow
> Integrity) on ARM32.
>
> For information about what CFI is, see:
> https://clang.llvm.org/docs/ControlFlowIntegrity.html
>
> For the kernel KCFI flavor, see:
> https://lwn.net/Articles/898040/
>
> The base changes required to bring up KCFI on ARM32 was mostly
> related to the use of custom vtables in the kernel, combined
> with defines to call into these vtable members directly from
> sites where they are used.
>
> We annotate all assembly calls that are called directly from
> C with SYM_TYPED_FUNC_START()/SYM_FUNC_END() so it is easy
> to see while reading the assembly that these functions are
> called from C and can have CFI prototype information prefixed
> to them.
>
> As protype prefix information is just some random bytes, it is
> not possible to "fall through" into an assembly function that
> is tagged with SYM_TYPED_FUNC_START(): there will be some
> binary noise in front of the function so this design pattern
> needs to be explicitly avoided at each site where it occurred.
>
> The approach to binding the calls to C is two-fold:
>
> - Either convert the affected vtable struct to C and provide
>   per-CPU prototypes for all the calls (done for TLB, cache)
>   or:
>
> - Provide prototypes in a special files just for CFI and tag
>   all these functions addressable.
>
> The permissive mode handles the new breakpoint type (0x03) that
> LLVM CLANG is emitting.
>
> To runtime-test the patches:
> - Enable CONFIG_LKDTM
> - echo CFI_FORWARD_PROTO > /sys/kernel/debug/provoke-crash/DIRECT
>
> The patch set has been booted to userspace on the following
> test platforms:
>
> - Arm Versatile (QEMU)
> - Arm Versatile Express (QEMU)
> - multi_v7 booted on Versatile Express (QEMU)
> - Footbridge Netwinder (SA110 ARMv4)
> - Ux500 (ARMv7 SMP)
> - Gemini (FA526)
>
> I am not saying there will not be corner cases that we need
> to fix in addition to this, but it is enough to get started.
> Looking at what was fixed for arm64 I am a bit weary that
> e.g. BPF might need something to trampoline properly.

CFI is disabled for BPF calls by default on architectures that don't
define __bpfcall, so it should mostly work. However, it should be
possible to add CFI support to the 32-bit arm BPF JIT following the
riscv and arm64 examples.

> But hopefullt people can get to testing it and help me fix
> remaining issues before the final version, or we can fix it
> in-tree.

Overall these patches look pretty good to me now, although the first
one doesn't seem necessary anymore. I also suspect some of the
function declaration lists could be made slightly less verbose with
macros, but that makes it harder to grep for them, so the current
format works for me too. For the series:

Reviewed-by: Sami Tolvanen <samitolvanen at google.com>

Sami



More information about the linux-arm-kernel mailing list