> On Aug 21, 2025, at 10:25, Peter Zijlstra <pet...@infradead.org> wrote:
> 
> On Thu, Aug 21, 2025 at 01:01:37PM +0200, Richard Biener wrote:
>> On Thu, 21 Aug 2025, Peter Zijlstra wrote:
>> 
>>> On Thu, Aug 21, 2025 at 01:16:56AM -0700, Andrew Pinski wrote:
>>> 
>>>>> +/* Compute KCFI type ID for a function declaration or function type
>>>>> (internal) */
>>>>> +static uint32_t
>>>>> +compute_kcfi_type_id (tree fntype_or_fndecl)
>>>>> +{
>>>>> +  if (!fntype_or_fndecl)
>>>>> +    return 0;
>>>>> +
>>>>> +  const char *canonical_name = mangle_function_type (fntype_or_fndecl);
>>>>> +  uint32_t base_type_id = kcfi_hash_string (canonical_name);
>>>>> 
>>>> 
>>>> Now I am curious why this needs to be a mangled function name? Since the
>>>> function in C the symbol is just its name.
>>>> Is there documentation that says the hash needs to be based on all of the
>>>> function arguments types?
>>> 
>>> The whole point of kCFI is to limit the targets of indirect calls to
>>> functions of the same signature. The actual function name is immaterial.
>> 
>> What's the attack vector and how does kCFI achieve mitigating it?
> 
> Any of the attacks that can result in scribbling a function pointer.
> Typically a buffer overflow I suppose.
> 
> 
> The way kCFI works is by changing the indirect call ABI. Traditionally
> the indirect call is simply:
> 
>  load-pointer-into-reg
>  call *%reg
> 
> kCFI changes every function to have a preamble like (with IBT and
> retpolines and all the modern crap on):

Does “every function” mean all the function in the compilation? Not only the 
function whose address is taken? 

Qing
> 
> __cfi_\func:
>  movl $0x12345678, %eax
>  nop
>  nop
>  nop
>  nop
>  nop
>  nop
>  nop
>  nop
>  nop
>  nop
>  nop
> \func:
>  endbr64
>  ...
> 
> And every indirect call site to:
> 
>  load-pointer-into-r11
>  movl $(-0x12345678), %r10d
>  addl $-15(%r11), %r10d
>  je   2f
> 1:ud2
>  .pushsection .kcfi_traps
>  .long 1b - .
>  .popsection
> 2:cs call __x86_indirect_thunk_r11 
> 
> Where 0x12345678 is the appropriate signature hash.
> 
> 
> So if the loaded pointer is scribbled somehow, the hash embedded at the
> callsite no longer matches the hash in the function preamble and #UD.
> 
> The kernel is also going to rewrite this if the hardware supports IBT,
> into a FineIBT sequence (with too many variants :-/), but I'll spare you
> those details.
> 
> Those people interested can find it here:
> 
>  
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/alternative.c#n1298
> 
> 
> 

Reply via email to