From: Kees Cook <kees@kernel.org>
To: Qing Zhao <qing.zhao@oracle.com>
Cc: Andrew Pinski <pinskia@gmail.com>,
Jakub Jelinek <jakub@redhat.com>,
Martin Uecker <uecker@tugraz.at>,
Richard Biener <rguenther@suse.de>,
Joseph Myers <josmyers@redhat.com>,
Peter Zijlstra <peterz@infradead.org>,
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>,
Dan Li <ashimida.1990@gmail.com>,
Sami Tolvanen <samitolvanen@google.com>,
Ramon de C Valle <rcvalle@google.com>,
Joao Moreira <joao@overdrivepizza.com>,
Nathan Chancellor <nathan@kernel.org>,
Bill Wendling <morbo@google.com>,
"gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>,
"linux-hardening@vger.kernel.org"
<linux-hardening@vger.kernel.org>
Subject: Re: [PATCH v3 2/7] kcfi: Add core Kernel Control Flow Integrity infrastructure
Date: Thu, 18 Sep 2025 11:20:59 -0700 [thread overview]
Message-ID: <202509181112.B39B490E@keescook> (raw)
In-Reply-To: <306E5909-C77F-415E-A2F4-6FAE3E5740DB@oracle.com>
On Thu, Sep 18, 2025 at 04:59:56PM +0000, Qing Zhao wrote:
>
>
> > On Sep 17, 2025, at 17:09, Kees Cook <kees@kernel.org> wrote:
> >
> > On Wed, Sep 17, 2025 at 01:42:32PM +0000, Qing Zhao wrote:
> >> This version of the middle-end change is much simpler and cleaner-:).
> >
> > Thanks! I think it's getter closer (hopefully). :)
> >
> >>> On Sep 13, 2025, at 19:23, Kees Cook <kees@kernel.org> wrote:
> [...]
> The above examples explain the whole picture very well.
> It might be a good idea to include them as comments of the routine “kcfi_prepare_alignment_nops”.
I've expanded this much more now for the future v4.
> >>> +- External functions that are address-taken have a weak __kcfi_typeid_$func
> >>> + symbol added with the typeid value available so that the typeid can be
> >>> + referenced from assembly linkages, etc, where the typeid values cannot be
> >>> + calculated (i.e where C type information is missing):
> >>> +
> >>> + .weak __kcfi_typeid_$func
> >>> + .set __kcfi_typeid_$func, $typeid
> >>> +
> >>
> >> From my previous understanding, the above weak symbol is emitted for external functions
> >> that are address-taken AND does not have a definition in the compilation. So the weak symbols
> >> Is emitted at the declaration site of the external function, is this true?
> >>
> >> If so, could you please clarify this in the above?
> >
> > Yes, this happens via assemble_external_real, which can be called under
> > a few conditions in gcc/varasm.cc.
>
> Okay. Please clarify this in the design doc.
I mention it later in the "behavioral" section:
- assemble_external_real calls kcfi_emit_typeid_symbol to add the
__kcfi_typeid_$func symbols.
I had left off implementation details (i.e. "called from
assemble_external_real") in the "constraints" section. How would you
like this arranged?
> >>> +- Keep indirect calls from being merged (see earlier example) by
> >>> + checking the KCFI insn's typeid for equality.
> >>
> >> Is this resolved by the following code:
> >>
> >> rtlanal.cc
> >> index 63a1d08c46cf..5016fe93ccac 100644
> >> --- a/gcc/rtlanal.cc
> >> +++ b/gcc/rtlanal.cc
> >> @@ -1177,6 +1177,11 @@ reg_referenced_p (const_rtx x, const_rtx body)
> >> case IF_THEN_ELSE:
> >> return reg_overlap_mentioned_p (x, body);
> >>
> >> + case KCFI:
> >> + /* For KCFI wrapper, check both the wrapped call and the type ID. */
> >> + return (reg_overlap_mentioned_p (x, XEXP (body, 0))
> >> + || reg_overlap_mentioned_p (x, XEXP (body, 1)));
> >> +
> >
> > The above is needed for accurate register "liveness" checking. When the
> > above code is removed, the kcfi-move-preservation.c regression test
> > fails (since it doesn't see the clobbers).
> Okay. I see.
> >
> > AFAICT, simply making it a new type of RTL (the DEF_RTL_EXPR), made it
> > unmergeable.
>
> Then is it possible some legal merging might not work anymore with this change?
Perhaps? I will see if I can construct a case where there should be a
"merged" call (when the typeid matches).
>
> > I assume this is because whatever was doing the call
> > merging was looking strictly for "CALL" types, but I honestly don't know
> > where that was happening.
> >
> >>> +/* Common helper for RTL patterns to emit .kcfi_traps section entry. */
> >>
> >> I noticed that you didn’t explain each parameter of the function in all the comments for the functions.
> >> This need to be updated for all the new functions.
> >
> > For externs like these, should the parameter documentation go in the .h
> > file, or the .cc file?
>
> My understanding is the parameter doc going in the .cc file (just double checked some gcc files to make sure this) -:)
Okay, thanks! I will update these.
> >
> >>> +void
> >>> +kcfi_emit_traps_section (FILE *file, rtx trap_label_sym)
> >>> +{
> >>> + /* Generate entry label internally and get its number. */
> >>> + rtx entry_label = gen_label_rtx ();
> >>> + int entry_labelno = CODE_LABEL_NUMBER (entry_label);
> >>
> >> Is the only usage of the new RTX “entry_label” is to generate a label_number?
> >> If so, the entry_label is not needed at all. You can get a distinct labelno for each
> >> Lkcfi_entry, for example, the function id for the current function.
> >
> > It is, yes. I can't use the function id because it's only incremented per
> > function and a given function may have multiple kcfi call sites within
> > it.
>
> Okay. I see.
>
> So, you need a unique lableno for each Lkcfi_entryN? Any other requirement?
Right, I need unique labels for each of trap, call, and entry. But they
are all associated together, so they could use a single counter.
> > I did have a version of this logic that used a kcfi-specific global
> > counter but (at the time) I was having trouble with it
>
> What kind of issue?
>
> > and had seen that
> > other "custom label" examples in the code base used this style, so I
> > switched to that.
>
> My concern is, the new generated RTX "entry_label” is not used at all, will there be any member leak from this?
>
>
> >
> > I have since figured out why the global counter wasn't work (I was using
> > it during expansion and not during insn output, so I had cases where a
> > call was getting duplicated and I had a repeated label). If it's
> > preferred, I could try switching back to the global counter to avoid
> > these "useless" gen_label_rtx calls?
>
> Yes, global counter approach is better.
Okay, I will switch to that.
>
> >
> >>> +static uint32_t
> >>> +kcfi_get_type_id (tree fn_type)
> >>> +{
> >>> + uint32_t type_id;
> >>> +
> >>> + /* Cache the attribute identifier. */
> >>> + if (!kcfi_type_id_attr)
> >>> + kcfi_type_id_attr = get_identifier ("kcfi_type_id");
> >>> +
> >>> + tree attr = lookup_attribute (IDENTIFIER_POINTER (kcfi_type_id_attr),
> >>> + TYPE_ATTRIBUTES (fn_type));
> >>
> >> The above can be simplified as:
> >> + tree attr = lookup_attribute (“kcfi_type_id”, TYPE_ATTRIBUTES (fn_type));
> >
> > Ugh, I totally misunderstood the examples I saw of this. I thought they
> > were caching the string lookup, but now that I look more closely, I see:
> >
> > #define IDENTIFIER_POINTER(NODE) \
> > ((const char *) IDENTIFIER_NODE_CHECK (NODE)->identifier.id.str)
> >
> > it's just returning the string!
> >
> > I will throw away the "caching" I was doing. I thought it would actually
> > look up the attribute using the tree returned by get_identifier, but I
> > see there is no overloaded lookup_attribute that takes a tree argument.
> >
> > *face palm*
>
> -:)
Okay, so I tried to remove this and remembered that it's actually cached
not for lookup_attribute, but for build_tree_list call case:
tree attr = build_tree_list (kcfi_type_id_attr, type_id_tree);
TYPE_ATTRIBUTES (fn_type) = chainon (TYPE_ATTRIBUTES (fn_type), attr);
For _that_, I need a "tree" argument. So instead of building it each
time, I have it built already, and I can get at its string for
lookup_attribute too. So I think this code is good as-is.
Thanks!
-Kees
--
Kees Cook
next prev parent reply other threads:[~2025-09-18 18:20 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-13 23:23 [PATCH v3 0/7] Introduce Kernel Control Flow Integrity ABI [PR107048] Kees Cook
2025-09-13 23:23 ` [PATCH v3 1/7] typeinfo: Introduce KCFI typeinfo mangling API Kees Cook
2025-09-17 17:56 ` Qing Zhao
2025-09-17 21:20 ` Kees Cook
2025-09-18 7:20 ` Martin Uecker
2025-09-18 18:09 ` Kees Cook
2025-09-18 18:40 ` Martin Uecker
2025-09-13 23:23 ` [PATCH v3 2/7] kcfi: Add core Kernel Control Flow Integrity infrastructure Kees Cook
2025-09-17 13:42 ` Qing Zhao
2025-09-17 21:09 ` Kees Cook
2025-09-18 16:59 ` Qing Zhao
2025-09-18 18:20 ` Kees Cook [this message]
2025-09-18 18:48 ` Qing Zhao
2025-09-18 19:20 ` Kees Cook
2025-09-18 19:39 ` Kees Cook
2025-09-18 20:14 ` Qing Zhao
2025-09-13 23:23 ` [PATCH v3 3/7] x86: Add x86_64 Kernel Control Flow Integrity implementation Kees Cook
2025-09-13 23:24 ` [PATCH v3 4/7] aarch64: Add AArch64 " Kees Cook
2025-09-13 23:43 ` Andrew Pinski
2025-09-14 19:45 ` Kees Cook
2025-09-14 19:52 ` Andrew Pinski
2025-09-17 20:01 ` Kees Cook
2025-09-13 23:24 ` [PATCH v3 5/7] arm: Add ARM 32-bit " Kees Cook
2025-09-13 23:24 ` [PATCH v3 6/7] riscv: Add RISC-V " Kees Cook
2025-09-13 23:24 ` [PATCH v3 7/7] kcfi: Add regression test suite Kees Cook
2025-09-13 23:51 ` Andrew Pinski
2025-09-17 19:51 ` Kees Cook
2025-09-13 23:58 ` Andrew Pinski
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=202509181112.B39B490E@keescook \
--to=kees@kernel.org \
--cc=andrew@sifive.com \
--cc=ashimida.1990@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=hubicka@ucw.cz \
--cc=jakub@redhat.com \
--cc=jim.wilson.gcc@gmail.com \
--cc=joao@overdrivepizza.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=morbo@google.com \
--cc=nathan@kernel.org \
--cc=palmer@dabbelt.com \
--cc=peterz@infradead.org \
--cc=pinskia@gmail.com \
--cc=qing.zhao@oracle.com \
--cc=rcvalle@google.com \
--cc=rguenther@suse.de \
--cc=richard.earnshaw@arm.com \
--cc=richard.sandiford@arm.com \
--cc=samitolvanen@google.com \
--cc=uecker@tugraz.at \
/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.