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>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <aUbODsjSuIBBLyo_@google.com>
Date: Sat, 20 Dec 2025 16:25:50 +0000
From: Carlos Llamas <cmllamas@...gle.com>
To: Josh Poimboeuf <jpoimboe@...nel.org>
Cc: x86@...nel.org, linux-kernel@...r.kernel.org,
	Petr Mladek <pmladek@...e.com>, Miroslav Benes <mbenes@...e.cz>,
	Joe Lawrence <joe.lawrence@...hat.com>,
	live-patching@...r.kernel.org, Song Liu <song@...nel.org>,
	laokz <laokz@...mail.com>, Jiri Kosina <jikos@...nel.org>,
	Marcos Paulo de Souza <mpdesouza@...e.com>,
	Weinan Liu <wnliu@...gle.com>,
	Fazla Mehrab <a.mehrab@...edance.com>,
	Chen Zhongjin <chenzhongjin@...wei.com>,
	Puranjay Mohan <puranjay@...nel.org>,
	Dylan Hatch <dylanbhatch@...gle.com>,
	Peter Zijlstra <peterz@...radead.org>,
	Heiko Carstens <hca@...ux.ibm.com>,
	Vasily Gorbik <gor@...ux.ibm.com>,
	Alexander Gordeev <agordeev@...ux.ibm.com>,
	Ard Biesheuvel <ardb@...nel.org>,
	Sami Tolvanen <samitolvanen@...gle.com>,
	Will Deacon <will@...nel.org>, kernel-team@...roid.com
Subject: Re: [PATCH v4 02/63] vmlinux.lds: Unify TEXT_MAIN, DATA_MAIN, and
 related macros

On Wed, Sep 17, 2025 at 09:03:10AM -0700, Josh Poimboeuf wrote:
> TEXT_MAIN, DATA_MAIN and friends are defined differently depending on
> whether certain config options enable -ffunction-sections and/or
> -fdata-sections.
> 
> There's no technical reason for that beyond voodoo coding.  Keeping the
> separate implementations adds unnecessary complexity, fragments the
> logic, and increases the risk of subtle bugs.
> 
> Unify the macros by using the same input section patterns across all
> configs.
> 
> This is a prerequisite for the upcoming livepatch klp-build tooling
> which will manually enable -ffunction-sections and -fdata-sections via
> KCFLAGS.
> 
> Cc: Heiko Carstens <hca@...ux.ibm.com>
> Cc: Vasily Gorbik <gor@...ux.ibm.com>
> Cc: Alexander Gordeev <agordeev@...ux.ibm.com>
> Signed-off-by: Josh Poimboeuf <jpoimboe@...nel.org>
> ---
>  include/asm-generic/vmlinux.lds.h | 40 ++++++++++---------------------
>  scripts/module.lds.S              | 12 ++++------
>  2 files changed, 17 insertions(+), 35 deletions(-)
> 
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index ae2d2359b79e9..6b2311fa41393 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -87,39 +87,24 @@
>  #define ALIGN_FUNCTION()  . = ALIGN(CONFIG_FUNCTION_ALIGNMENT)
>  
>  /*
> - * LD_DEAD_CODE_DATA_ELIMINATION option enables -fdata-sections, which
> - * generates .data.identifier sections, which need to be pulled in with
> - * .data. We don't want to pull in .data..other sections, which Linux
> - * has defined. Same for text and bss.
> + * Support -ffunction-sections by matching .text and .text.*,
> + * but exclude '.text..*'.
>   *
> - * With LTO_CLANG, the linker also splits sections by default, so we need
> - * these macros to combine the sections during the final link.
> - *
> - * With AUTOFDO_CLANG and PROPELLER_CLANG, by default, the linker splits
> - * text sections and regroups functions into subsections.
> - *
> - * RODATA_MAIN is not used because existing code already defines .rodata.x
> - * sections to be brought in with rodata.
> + * Special .text.* sections that are typically grouped separately, such as
> + * .text.unlikely or .text.hot, must be matched explicitly before using
> + * TEXT_MAIN.
>   */
> -#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG) || \
> -defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
>  #define TEXT_MAIN .text .text.[0-9a-zA-Z_]*
> -#else
> -#define TEXT_MAIN .text
> -#endif
> -#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG)
> +
> +/*
> + * Support -fdata-sections by matching .data, .data.*, and others,
> + * but exclude '.data..*'.
> + */
>  #define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data.rel.* .data..L* .data..compoundliteral* .data.$__unnamed_* .data.$L*
>  #define SDATA_MAIN .sdata .sdata.[0-9a-zA-Z_]*
>  #define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]* .rodata..L*
>  #define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* .bss..L* .bss..compoundliteral*
>  #define SBSS_MAIN .sbss .sbss.[0-9a-zA-Z_]*
> -#else
> -#define DATA_MAIN .data .data.rel .data.rel.local
> -#define SDATA_MAIN .sdata
> -#define RODATA_MAIN .rodata
> -#define BSS_MAIN .bss
> -#define SBSS_MAIN .sbss
> -#endif
>  
>  /*
>   * GCC 4.5 and later have a 32 bytes section alignment for structures.
> @@ -580,9 +565,8 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
>   * during second ld run in second ld pass when generating System.map
>   *
>   * TEXT_MAIN here will match symbols with a fixed pattern (for example,
> - * .text.hot or .text.unlikely) if dead code elimination or
> - * function-section is enabled. Match these symbols first before
> - * TEXT_MAIN to ensure they are grouped together.
> + * .text.hot or .text.unlikely).  Match those before TEXT_MAIN to ensure
> + * they get grouped together.
>   *
>   * Also placing .text.hot section at the beginning of a page, this
>   * would help the TLB performance.
> diff --git a/scripts/module.lds.S b/scripts/module.lds.S
> index ee79c41059f3d..2632c6cb8ebe7 100644
> --- a/scripts/module.lds.S
> +++ b/scripts/module.lds.S
> @@ -38,12 +38,10 @@ SECTIONS {
>  	__kcfi_traps 		: { KEEP(*(.kcfi_traps)) }
>  #endif
>  
> -#ifdef CONFIG_LTO_CLANG
> -	/*
> -	 * With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and
> -	 * -ffunction-sections, which increases the size of the final module.
> -	 * Merge the split sections in the final binary.
> -	 */
> +	.text : {
> +		*(.text .text.[0-9a-zA-Z_]*)
> +	}
> +

Cc: Ard Biesheuvel <ardb@...nel.org>
Cc: Sami Tolvanen <samitolvanen@...gle.com>

I'm seeing some KP when trying to load modules after this change. I
believe there is some sort of incompatibility with the SCS (Shadow Call
Stack) code in arm64? The panic is always on __pi_scs_handle_fde_frame:

  init: Loading module [...]/drivers/net/wireless/virtual/mac80211_hwsim.ko
  Unable to handle kernel paging request at virtual address ffffffe6468f0ffc
  [...]
  pc : __pi_scs_handle_fde_frame+0xd8/0x15c
  lr : __pi_$x+0x74/0x138
  sp : ffffffc08005bb10
  x29: ffffffc08005bb10 x28: ffffffc081873010 x27: 0000000000000000
  x26: 0000000000000007 x25: 0000000000000000 x24: 0000000000000000
  x23: 0000000000000001 x22: ffffffe649794fa0 x21: ffffffe6469190b4
  x20: 000000000000182c x19: 0000000000000001 x18: ffffffc080053000
  x17: 000000000000002d x16: ffffffe6469190c5 x15: ffffffe6468f1000
  x14: 000000000000003e x13: ffffffe6469190c6 x12: 00000000d50323bf
  x11: 00000000d503233f x10: ffffffe649119cb8 x9 : ffffffe6468f1000
  x8 : 0000000000000100 x7 : 00656d6172665f68 x6 : 0000000000000001
  x5 : 6372610000000000 x4 : 0000008000000000 x3 : 0000000000000000
  x2 : ffffffe647e528f4 x1 : 0000000000000001 x0 : 0000000000000004
  Call trace:
   __pi_scs_handle_fde_frame+0xd8/0x15c (P)
   module_finalize+0xfc/0x164
   post_relocation+0xbc/0xd8
   load_module+0xfd4/0x11a8
   __arm64_sys_finit_module+0x23c/0x328
   invoke_syscall+0x58/0xe4
   el0_svc_common+0x80/0xdc
   do_el0_svc+0x1c/0x28
   el0_svc+0x54/0x1c4
   el0t_64_sync_handler+0x68/0xdc
   el0t_64_sync+0x1c4/0x1c8
  Code: 54fffd4c 1400001f 3707ff63 aa0903ef (b85fcdf0)

This is not a problem if I disable UNWIND_PATCH_PAC_INTO_SCS but I have
no idea why. Looking around it seems like this might related:

  $ cat arch/arm64/include/asm/module.lds.h
  SECTIONS {
  [...]
  #ifdef CONFIG_UNWIND_TABLES
        /*
         * Currently, we only use unwind info at module load time, so we can
         * put it into the .init allocation.
         */
        .init.eh_frame : { *(.eh_frame) }
  #endif

I must note that I've only seen this in Android kernels and I have not
tried to reproduce the issue elsewhere. However, the incompatibility
seems like it could be applicable upstream too and I'm hoping that the
issue is evident to others (I can't understand any of this).

Thanks,
--
Carlos Llamas

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ