[PATCH] x86/mm: Ensure clear_page() variants always have __kcfi_typeid_ symbols

Nathan Chancellor posted 1 patch 2 months ago
There is a newer version of this series
arch/x86/include/asm/page_64.h | 3 +++
1 file changed, 3 insertions(+)
[PATCH] x86/mm: Ensure clear_page() variants always have __kcfi_typeid_ symbols
Posted by Nathan Chancellor 2 months ago
When building with CONFIG_CFI=y and CONFIG_LTO_CLANG_FULL=y, there is a
series of errors from the various versions of clear_page() not having
__kcfi_typeid_ symbols.

  $ cat kernel/configs/repro.config
  CONFIG_CFI=y
  # CONFIG_LTO_NONE is not set
  CONFIG_LTO_CLANG_FULL=y

  $ make -skj"$(nproc)" ARCH=x86_64 LLVM=1 clean defconfig repro.config bzImage
  ld.lld: error: undefined symbol: __kcfi_typeid_clear_page_rep
  >>> referenced by ld-temp.o
  >>>               vmlinux.o:(__cfi_clear_page_rep)

  ld.lld: error: undefined symbol: __kcfi_typeid_clear_page_orig
  >>> referenced by ld-temp.o
  >>>               vmlinux.o:(__cfi_clear_page_orig)

  ld.lld: error: undefined symbol: __kcfi_typeid_clear_page_erms
  >>> referenced by ld-temp.o
  >>>               vmlinux.o:(__cfi_clear_page_erms)

With full LTO, it is possible for LLVM to realize that these functions
never have their address taken (as they are only used within an
alternative, which will make them a direct call) across the whole kernel
and either drop or skip generating their kCFI type identification
symbols.

clear_page_{rep,orig,erms}() are defined in clear_page_64.S with
SYM_TYPED_FUNC_START as a result of commit 2981557cb040 ("x86,kcfi: Fix
EXPORT_SYMBOL vs kCFI"), as exported functions are free to be called
indirectly thus need kCFI type identifiers.

Use KCFI_REFERENCE with these clear_page() functions to force LLVM to
see these functions as address-taken and generate then keep the kCFI
type identifiers.

Fixes: 2981557cb040 ("x86,kcfi: Fix EXPORT_SYMBOL vs kCFI")
Closes: https://github.com/ClangBuiltLinux/linux/issues/2128
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
---
Alternatively, these functions could move back to SYM_FUNC_START with a
comment that they need to be exported to be called via the alternative
in clear_page() but they are never expected to be called indirectly.
---
 arch/x86/include/asm/page_64.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h
index 015d23f3e01f..53f4089333f2 100644
--- a/arch/x86/include/asm/page_64.h
+++ b/arch/x86/include/asm/page_64.h
@@ -43,6 +43,9 @@ extern unsigned long __phys_addr_symbol(unsigned long);
 void clear_page_orig(void *page);
 void clear_page_rep(void *page);
 void clear_page_erms(void *page);
+KCFI_REFERENCE(clear_page_orig);
+KCFI_REFERENCE(clear_page_rep);
+KCFI_REFERENCE(clear_page_erms);
 
 static inline void clear_page(void *page)
 {

---
base-commit: 3a8660878839faadb4f1a6dd72c3179c1df56787
change-id: 20251013-x86-fix-clear_page-cfi-full-lto-errors-173faa536840

Best regards,
--  
Nathan Chancellor <nathan@kernel.org>
Re: [PATCH] x86/mm: Ensure clear_page() variants always have __kcfi_typeid_ symbols
Posted by Borislav Petkov 1 month, 2 weeks ago
Hey Nathan,

On Mon, Oct 13, 2025 at 02:27:36PM -0700, Nathan Chancellor wrote:
> When building with CONFIG_CFI=y and CONFIG_LTO_CLANG_FULL=y, there is a
> series of errors from the various versions of clear_page() not having
> __kcfi_typeid_ symbols.

might wanna wait with this one - those are going away except one:

https://lore.kernel.org/r/20251027202109.678022-5-ankur.a.arora@oracle.com

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette
Re: [PATCH] x86/mm: Ensure clear_page() variants always have __kcfi_typeid_ symbols
Posted by Nathan Chancellor 1 month, 2 weeks ago
Hey Boris,

On Thu, Oct 30, 2025 at 08:28:19PM +0100, Borislav Petkov wrote:
> On Mon, Oct 13, 2025 at 02:27:36PM -0700, Nathan Chancellor wrote:
> > When building with CONFIG_CFI=y and CONFIG_LTO_CLANG_FULL=y, there is a
> > series of errors from the various versions of clear_page() not having
> > __kcfi_typeid_ symbols.
> 
> might wanna wait with this one - those are going away except one:
> 
> https://lore.kernel.org/r/20251027202109.678022-5-ankur.a.arora@oracle.com

These errors occur in Linus's tree so could this go before that one then
it could just update the instances of KCFI_ADDRESSABLE? I don't have a
strong opinion, I found these series of errors tangentially but this
feels like something that could go via x86/urgent and that series could
just rebase on it.

Cheers,
Nathan
Re: [PATCH] x86/mm: Ensure clear_page() variants always have __kcfi_typeid_ symbols
Posted by Borislav Petkov 1 month, 2 weeks ago
On Fri, Oct 31, 2025 at 10:20:44AM -0400, Nathan Chancellor wrote:
> These errors occur in Linus's tree so could this go before that one then
> it could just update the instances of KCFI_ADDRESSABLE? I don't have a
> strong opinion, I found these series of errors tangentially but this
> feels like something that could go via x86/urgent and that series could
> just rebase on it.

Sure, that works too.

I guess we want that in stable too, considering where the Fixes: tag commit
landed...?

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette
Re: [PATCH] x86/mm: Ensure clear_page() variants always have __kcfi_typeid_ symbols
Posted by Nathan Chancellor 1 month, 2 weeks ago
On Fri, Oct 31, 2025 at 03:46:24PM +0100, Borislav Petkov wrote:
> On Fri, Oct 31, 2025 at 10:20:44AM -0400, Nathan Chancellor wrote:
> > These errors occur in Linus's tree so could this go before that one then
> > it could just update the instances of KCFI_ADDRESSABLE? I don't have a
> > strong opinion, I found these series of errors tangentially but this
> > feels like something that could go via x86/urgent and that series could
> > just rebase on it.
> 
> Sure, that works too.
> 
> I guess we want that in stable too, considering where the Fixes: tag commit
> landed...?

Yeah, I should have explicitly tagged this change for stable but I have
been a little lazy since AUTOSEL often picks up the slack :) If you want
a resend with that adjusted, let me know.

Cheers,
Nathan
Re: [PATCH] x86/mm: Ensure clear_page() variants always have __kcfi_typeid_ symbols
Posted by Borislav Petkov 1 month, 2 weeks ago
On Fri, Oct 31, 2025 at 04:22:26PM -0400, Nathan Chancellor wrote:
> Yeah, I should have explicitly tagged this change for stable but I have
> been a little lazy since AUTOSEL often picks up the slack :) If you want
> a resend with that adjusted, let me know.

Nah, that's fine.

I'm asking explicitly because we have this basic rule:

stable material => urgent branch and goes to Linus now

So it basically determines where I route it to.

Lemme take care of it.

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette
Re: [PATCH] x86/mm: Ensure clear_page() variants always have __kcfi_typeid_ symbols
Posted by Sami Tolvanen 1 month, 3 weeks ago
Hi Nathan,

On Mon, Oct 13, 2025 at 2:27 PM Nathan Chancellor <nathan@kernel.org> wrote:
>
> When building with CONFIG_CFI=y and CONFIG_LTO_CLANG_FULL=y, there is a
> series of errors from the various versions of clear_page() not having
> __kcfi_typeid_ symbols.
>
>   $ cat kernel/configs/repro.config
>   CONFIG_CFI=y
>   # CONFIG_LTO_NONE is not set
>   CONFIG_LTO_CLANG_FULL=y
>
>   $ make -skj"$(nproc)" ARCH=x86_64 LLVM=1 clean defconfig repro.config bzImage
>   ld.lld: error: undefined symbol: __kcfi_typeid_clear_page_rep
>   >>> referenced by ld-temp.o
>   >>>               vmlinux.o:(__cfi_clear_page_rep)
>
>   ld.lld: error: undefined symbol: __kcfi_typeid_clear_page_orig
>   >>> referenced by ld-temp.o
>   >>>               vmlinux.o:(__cfi_clear_page_orig)
>
>   ld.lld: error: undefined symbol: __kcfi_typeid_clear_page_erms
>   >>> referenced by ld-temp.o
>   >>>               vmlinux.o:(__cfi_clear_page_erms)
>
> With full LTO, it is possible for LLVM to realize that these functions
> never have their address taken (as they are only used within an
> alternative, which will make them a direct call) across the whole kernel
> and either drop or skip generating their kCFI type identification
> symbols.
>
> clear_page_{rep,orig,erms}() are defined in clear_page_64.S with
> SYM_TYPED_FUNC_START as a result of commit 2981557cb040 ("x86,kcfi: Fix
> EXPORT_SYMBOL vs kCFI"), as exported functions are free to be called
> indirectly thus need kCFI type identifiers.
>
> Use KCFI_REFERENCE with these clear_page() functions to force LLVM to
> see these functions as address-taken and generate then keep the kCFI
> type identifiers.
>
> Fixes: 2981557cb040 ("x86,kcfi: Fix EXPORT_SYMBOL vs kCFI")
> Closes: https://github.com/ClangBuiltLinux/linux/issues/2128
> Signed-off-by: Nathan Chancellor <nathan@kernel.org>
> ---
> Alternatively, these functions could move back to SYM_FUNC_START with a
> comment that they need to be exported to be called via the alternative
> in clear_page() but they are never expected to be called indirectly.

Right, this might be a cleaner solution if we don't actually expect
these to be indirectly called.

> ---
>  arch/x86/include/asm/page_64.h | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h
> index 015d23f3e01f..53f4089333f2 100644
> --- a/arch/x86/include/asm/page_64.h
> +++ b/arch/x86/include/asm/page_64.h
> @@ -43,6 +43,9 @@ extern unsigned long __phys_addr_symbol(unsigned long);
>  void clear_page_orig(void *page);
>  void clear_page_rep(void *page);
>  void clear_page_erms(void *page);
> +KCFI_REFERENCE(clear_page_orig);
> +KCFI_REFERENCE(clear_page_rep);
> +KCFI_REFERENCE(clear_page_erms);

In any case,

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

Sami