lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20251013-x86-fix-clear_page-cfi-full-lto-errors-v1-1-d69534c0be61@kernel.org>
Date: Mon, 13 Oct 2025 14:27:36 -0700
From: Nathan Chancellor <nathan@...nel.org>
To: Peter Zijlstra <peterz@...radead.org>, 
 Thomas Gleixner <tglx@...utronix.de>, Ingo Molnar <mingo@...hat.com>, 
 Borislav Petkov <bp@...en8.de>, Dave Hansen <dave.hansen@...ux.intel.com>, 
 x86@...nel.org, Sami Tolvanen <samitolvanen@...gle.com>
Cc: linux-kernel@...r.kernel.org, llvm@...ts.linux.dev, 
 Nathan Chancellor <nathan@...nel.org>
Subject: [PATCH] x86/mm: Ensure clear_page() variants always have
 __kcfi_typeid_ symbols

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@...nel.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@...nel.org>


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ