Hi Mark, Sorry for the late reply. On 01/03, Mark Rutland wrote: > On Sun, Dec 18, 2022 at 10:17:58PM -0800, Dan Li wrote: > > If there are user mode programs or other systems that want to use > > this feature, it may be more convenient to use a callback (so this > > compilation option is set to -fsanitize=cfi instead of kcfi). > > I appreciate that may be nicer for userspace, but it would be far nicer for the > kernel if we could have a kcfi mode that behaves the same as LLVM, using a BRK. > That's going to be simpler for the kernel to deal with, and should result in > nicer code / smaller binary size (for the reasons given above). > > Can we please have an LLVM-compatible KCFI mode, and have the -fsanitize=cfi be > a separate option from -fsanitize=kcfi? Ok, in the next version I will change to the same option as clang :) > > > 2. A reserved typeid (such as 0x0U on the aarch64 platform) is always > > inserted in front of functions that should not be called indirectly. > > Functions that can be called indirectly will not use this hash value, > > which prevents instructions/data before the function from being used > > as a typeid by an attacker. > > That sounds sensible, though it meanse we'll need to go audit all the assembly > without type annotations. > > I presume that "functions that should not be called indirectly" only includes > those which are not directly visible outside the compilation unit AND whose > address is never taken / escaped from the compilation unit. Is that the case? Yes. > > > 3. Some bits are ignored in the typeid to avoid conflicts between the > > typeid and the instruction set of a specific platform, thereby > > preventing an attacker from bypassing the CFI check by using the > > instruction as a typeid, such as on the aarch64 platform: > > * If the following instruction sequence exists: > > 400620: a9be7bfd stp x29, x30, [sp, #-32]! > > 400624: 910003fd mov x29, sp > > 400628: f9000bf3 str x19, [sp, #16] > > * If the expected typeid of the indirect call is exactly 0x910003fd, > > the attacker can jump to the next instruction position of any > > "mov x29,sp" instruction (such as 0x400628 here). > > Which bits exactly are ignored on arm64? > > e.g. are these encoded into UDF immediates? In aarch64, I currently ignore bit [28:27]. IUCC, according to the manual[1], it is a UDF instruction only when the upper 16 bits are all 0. But due to this has too much impact on the entropy of typeid, so I (not rigorously) only ignore 2 bits here, and most of the instruction codes covered by it belong to 'Reserved' or 'UNALLOCATED' (probably not a good idea). But as Kees said, if clang doesn't handle it here, in order to be consistent, I think it's better for gcc to not handle it when implementing kernel cfi. [1] https://developer.arm.com/documentation/ddi0602/2022-06/Index-by-Encoding?lang=en > > As a general thing, how does this work with -fpatchable-function-entry=M,N, > where N is non-zero? > > We still need to fix that for LLVM, and it would be good to align on the same behaviour. > Yeah, it makes sense. Currently, it is consistent with llvm. Taking -fpatchable-function-entry=2,1 as an example, the currently generated code is as follows: __cfi_main: .4byte 0x439d3502 .global main .section __patchable_function_entries .align 3 .8byte .LPFE3 .text .LPFE3: nop .type main, %function main: nop .LFB2: .cfi_startproc stp x29, x30, [sp, -32]! Finally, do we want to generate code like this? nop .4byte 0x439d3502 main: nop ... Thanks, Dan. > > > > -- > > 2.17.1 > >