From: Kees Cook <kees@kernel.org>
To: Qing Zhao <qing.zhao@oracle.com>
Cc: Andrew Pinski <andrew.pinski@oss.qualcomm.com>,
"gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>,
Joseph Myers <josmyers@redhat.com>,
Richard Biener <rguenther@suse.de>, Jan Hubicka <hubicka@ucw.cz>,
Richard Earnshaw <richard.earnshaw@arm.com>,
Richard Sandiford <richard.sandiford@arm.com>,
Marcus Shawcroft <marcus.shawcroft@arm.com>,
Kyrylo Tkachov <kyrylo.tkachov@arm.com>,
Kito Cheng <kito.cheng@gmail.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Andrew Waterman <andrew@sifive.com>,
Jim Wilson <jim.wilson.gcc@gmail.com>,
Peter Zijlstra <peterz@infradead.org>,
Dan Li <ashimida.1990@gmail.com>,
"linux-hardening@vger.kernel.org"
<linux-hardening@vger.kernel.org>
Subject: Re: [RFC PATCH 2/7] mangle: Introduce C typeinfo mangling API
Date: Fri, 22 Aug 2025 12:02:01 -0700 [thread overview]
Message-ID: <202508221149.F19A56772@keescook> (raw)
In-Reply-To: <22C19D00-58D7-4854-915E-C7B8CDB3317E@oracle.com>
On Fri, Aug 22, 2025 at 03:11:16PM +0000, Qing Zhao wrote:
> > On Aug 21, 2025, at 17:29, Kees Cook <kees@kernel.org> wrote:
> > For non-static functions, we cannot know if other compilation units may
> > make indirect calls to a given function, so those functions must always
> > have their kcfi preamble added. For static functions, if they are
> > address-taken by the current compilation unit, then they must get a kcfi
> > preamble added.
>
> Oh, yeah, I see. without lto or whole-program-mode, we cannot determine
> whether a extern function is address taken or not. Therefore, we have to
> treat ALL extern functions conservatively as address taken.
>
> So, from my understanding, the complete list that need to compute the typeid from the function prototype is:
>
> - At indirect call sites
> - all indirect call sites; (At the call site)
> - At function preambles
> - all address-taken static functions (At the function definition)
> - all extern functions (At function declaration or function definition?? Please see my question below)
For "extern functions", the logic is split as:
- "all extern function definitions get preamble"
- "all extern function declarations without a definition that are
address-taken get __kcfi_typeid_ symbol"
> > The other case is emitting the __ckfi_typeid_FUNC weak symbols, which is
> > used for link-time resolution with non-C code (i.e. raw .S assembly)
> > which doesn't have access to the C type system to calculate the hashes
> > on its own, and needs to have a way to build its own kcfi preambles.
>
> So, for such functions, there should be an extern function declaration in the C code.
> But the definition of such function is not available in the C code we are compiling.
> Therefore the weak __ckfi_typeid_FUNC symbol is emitted at the function declaration
> point for such function when we compile the C code?
>
> And the typeid (the hash value) for such routine is computed at the function declaration
> point too.
>
> Is the above understanding correct?
Correct, the kcfi_typeid symbol and value are emitted at function
declaration point, but only if such function is address-taken.
> Then for the other extern function whose definition is in the C code of other modules that might
> be compiled later, should the typeid is computed at the declaration or the definition?
It is computed and emitted just for externs that are address-taken.
> > This
> > is how Linux constructs its assembly function entry points:
> >
> > #ifndef __CFI_TYPE
> > #define __CFI_TYPE(name) \
> > .4byte __kcfi_typeid_##name
> > #endif
> >
> > #define SYM_TYPED_ENTRY(name, linkage, align...) \
> > linkage(name) ASM_NL \
> > align ASM_NL \
> > __CFI_TYPE(name) ASM_NL \
> > name:
> >
> > That way all the asm functions can be be indirect call targets without
> > knowing the hash value (which will be filled in at link time).
>
> Okay. I see. This is the case for the extern function whose definition is in the assembly file. (Not available in
> the C code)
Right, and sometimes we have to explicitly perform a no-op
address-taking to make sure a symbol gets generated:
/*
* Force the compiler to emit 'sym' as a symbol, so that we can reference
* it from inline assembler. Necessary in case 'sym' could be inlined
* otherwise, or eliminated entirely due to lack of references that are
* visible to the compiler.
*/
#define ___ADDRESSABLE(sym, __attrs) \
static void * __used __attrs \
__UNIQUE_ID(__PASTE(__addressable_,sym)) = (void *)(uintptr_t)&sym;
#define __ADDRESSABLE(sym) \
___ADDRESSABLE(sym, __section(".discard.addressable"))
$ git grep KCFI_REFERENCE
include/linux/compiler.h:#define KCFI_REFERENCE(sym) __ADDRESSABLE(sym)
arch/x86/include/asm/page_64.h:KCFI_REFERENCE(copy_page);
arch/x86/include/asm/string_64.h:KCFI_REFERENCE(__memset);
arch/x86/include/asm/string_64.h:KCFI_REFERENCE(__memmove);
arch/x86/kernel/alternative.c:KCFI_REFERENCE(__bpf_prog_runX);
arch/x86/kernel/alternative.c:KCFI_REFERENCE(__bpf_callback_fn);
> > I assume I just didn't see how yet. :) I wasn't able to identify nor
> > store the typeid for function definitions that ultimately end up getting
> > .s file output.
> So, the problem only exists for the external functions whose definition is NOT in the C code?
Yup!
> > I couldn't figure out how to find these during the GIMPLE pass. Oh,
> > perhaps I can do this with an IPA pass? That should let me walk all
> > functions including externs. I'll give it a try...
Adding the IPA pass to find all functions worked perfectly. I was able
to remove all the weird DECL reconstruction and just use the original
FUNCTION_TYPE info for the typeids.
-Kees
--
Kees Cook
next prev parent reply other threads:[~2025-08-22 19:02 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-21 7:26 [RFC PATCH 0/7] Introduce Kernel Control Flow Integrity ABI [PR107048] Kees Cook
2025-08-21 7:26 ` [RFC PATCH 1/7] sanitizer: Expand sanitizer flag from 32-bit to 64-bit Kees Cook
2025-08-21 7:26 ` [RFC PATCH 2/7] mangle: Introduce C typeinfo mangling API Kees Cook
[not found] ` <CALvbMcAPV1eB6nocPAS=qR8SCiQyU43v911R8S7Ah_=G7yK-+g@mail.gmail.com>
2025-08-21 8:29 ` Andrew Pinski
2025-08-21 16:16 ` Kees Cook
2025-08-21 16:24 ` Andrew Pinski
2025-08-21 19:14 ` Qing Zhao
2025-08-21 21:29 ` Kees Cook
2025-08-22 15:11 ` Qing Zhao
2025-08-22 19:02 ` Kees Cook [this message]
2025-08-22 20:29 ` Qing Zhao
2025-08-22 22:29 ` Kees Cook
2025-08-25 8:13 ` Peter Zijlstra
2025-08-25 13:56 ` Qing Zhao
2025-08-21 7:26 ` [RFC PATCH 3/7] kcfi: Add core Kernel Control Flow Integrity infrastructure Kees Cook
[not found] ` <CALvbMcA+8iHo+zCCvs4UdAg9PVQVtgOno-rtMS4i5YajrjkyGw@mail.gmail.com>
2025-08-21 9:12 ` Peter Zijlstra
2025-08-21 11:01 ` Richard Biener
2025-08-21 14:25 ` Peter Zijlstra
2025-08-21 18:09 ` Qing Zhao
2025-08-22 5:15 ` Kees Cook
2025-08-22 10:03 ` Peter Zijlstra
2025-08-21 19:57 ` Kees Cook
2025-08-22 6:53 ` Richard Biener
2025-08-22 19:23 ` Kees Cook
[not found] ` <CA+=Sn1koTTQaXDnAVWtVU6ACWwhD08NR5nDJO236Pmcoi2X9qA@mail.gmail.com>
2025-08-22 7:51 ` Peter Zijlstra
2025-08-22 8:24 ` Peter Zijlstra
2025-08-22 8:47 ` Kees Cook
2025-08-22 5:10 ` Kees Cook
2025-08-22 5:27 ` Andrew Pinski
2025-08-28 14:57 ` Qing Zhao
2025-09-04 4:24 ` Kees Cook
2025-09-04 7:16 ` Peter Zijlstra
2025-09-04 14:41 ` Qing Zhao
2025-08-21 7:26 ` [RFC PATCH 4/7] x86: Add x86_64 Kernel Control Flow Integrity implementation Kees Cook
2025-08-21 9:29 ` Peter Zijlstra
2025-08-21 18:46 ` Kees Cook
2025-08-21 19:03 ` Kees Cook
2025-08-22 8:19 ` Peter Zijlstra
2025-08-22 8:36 ` Kees Cook
2025-08-22 8:55 ` Peter Zijlstra
2025-08-21 7:26 ` [RFC PATCH 5/7] aarch64: Add AArch64 " Kees Cook
2025-08-21 7:26 ` [RFC PATCH 6/7] riscv: Add RISC-V " Kees Cook
2025-08-21 7:26 ` [RFC PATCH 7/7] kcfi: Add regression test suite Kees Cook
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=202508221149.F19A56772@keescook \
--to=kees@kernel.org \
--cc=andrew.pinski@oss.qualcomm.com \
--cc=andrew@sifive.com \
--cc=ashimida.1990@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=hubicka@ucw.cz \
--cc=jim.wilson.gcc@gmail.com \
--cc=josmyers@redhat.com \
--cc=kito.cheng@gmail.com \
--cc=kyrylo.tkachov@arm.com \
--cc=linux-hardening@vger.kernel.org \
--cc=marcus.shawcroft@arm.com \
--cc=palmer@dabbelt.com \
--cc=peterz@infradead.org \
--cc=qing.zhao@oracle.com \
--cc=rguenther@suse.de \
--cc=richard.earnshaw@arm.com \
--cc=richard.sandiford@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.