From 4afc71bba8b7d7841681e7647ae02f5079aaf28f Mon Sep 17 00:00:00 2001 From: Joe Lawrence Date: Wed, 4 Mar 2026 20:52:37 -0500 Subject: module.lds,codetag: force 0 sh_addr for sections Commit 1ba9f8979426 ("vmlinux.lds: Unify TEXT_MAIN, DATA_MAIN, and related macros") added .text and made .data, .bss, and .rodata sections unconditional in the module linker script, but without an explicit address like the other sections in the same file. When linking modules with ld.bfd -r, sections defined without an address inherit the location counter, resulting in non-zero sh_addr values in the .ko. Relocatable objects are expected to have sh_addr=0 for these sections and these non-zero addresses confuse elfutils and have been reported to cause segmentation faults in SystemTap [1]. Add the 0 address specifier to all sections in module.lds, including the .codetag.* sections via MOD_SEPARATE_CODETAG_SECTIONS macro. Link: https://sourceware.org/bugzilla/show_bug.cgi?id=33958 Fixes: 1ba9f8979426 ("vmlinux.lds: Unify TEXT_MAIN, DATA_MAIN, and related macros") Signed-off-by: Joe Lawrence Reviewed-by: Petr Pavlu Acked-by: Josh Poimboeuf Signed-off-by: Sami Tolvanen --- scripts/module.lds.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/module.lds.S b/scripts/module.lds.S index 054ef99e8288..e1cab3cee3f7 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -32,30 +32,30 @@ SECTIONS { __jump_table 0 : ALIGN(8) { KEEP(*(__jump_table)) } __ex_table 0 : ALIGN(4) { KEEP(*(__ex_table)) } - __patchable_function_entries : { *(__patchable_function_entries) } + __patchable_function_entries 0 : { *(__patchable_function_entries) } .init.klp_funcs 0 : ALIGN(8) { KEEP(*(.init.klp_funcs)) } .init.klp_objects 0 : ALIGN(8) { KEEP(*(.init.klp_objects)) } #ifdef CONFIG_ARCH_USES_CFI_TRAPS - __kcfi_traps : { KEEP(*(.kcfi_traps)) } + __kcfi_traps 0 : { KEEP(*(.kcfi_traps)) } #endif - .text : { + .text 0 : { *(.text .text.[0-9a-zA-Z_]*) } - .bss : { + .bss 0 : { *(.bss .bss.[0-9a-zA-Z_]*) *(.bss..L*) } - .data : { + .data 0 : { *(.data .data.[0-9a-zA-Z_]*) *(.data..L*) } - .rodata : { + .rodata 0 : { *(.rodata .rodata.[0-9a-zA-Z_]*) *(.rodata..L*) } -- cgit v1.2.3 From e340db306c3bb85877490f33a78eb80549ac43a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 5 Mar 2026 10:31:43 +0100 Subject: sign-file: use 'struct module_signature' from the UAPI headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the UAPI headers provide the required definitions, use those. Some symbols have been renamed, adapt to those. Also adapt the include path for the custom sign-file rule in the bpf selftests. Signed-off-by: Thomas Weißschuh Reviewed-by: Petr Pavlu Reviewed-by: Nicolas Schier Signed-off-by: Sami Tolvanen --- scripts/Makefile | 1 + scripts/sign-file.c | 19 ++++--------------- 2 files changed, 5 insertions(+), 15 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile b/scripts/Makefile index 0941e5ce7b57..3434a82a119f 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -35,6 +35,7 @@ HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include HOSTLDLIBS_sorttable = -lpthread HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include HOSTCFLAGS_sign-file.o = $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null) +HOSTCFLAGS_sign-file.o += -I$(srctree)/tools/include/uapi/ HOSTLDLIBS_sign-file = $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto) ifdef CONFIG_UNWINDER_ORC diff --git a/scripts/sign-file.c b/scripts/sign-file.c index 73fbefd2e540..86b010ac1514 100644 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -40,19 +40,7 @@ #endif #include "ssl-common.h" -struct module_signature { - uint8_t algo; /* Public-key crypto algorithm [0] */ - uint8_t hash; /* Digest algorithm [0] */ - uint8_t id_type; /* Key identifier type [PKEY_ID_PKCS7] */ - uint8_t signer_len; /* Length of signer's name [0] */ - uint8_t key_id_len; /* Length of key identifier [0] */ - uint8_t __pad[3]; - uint32_t sig_len; /* Length of signature data */ -}; - -#define PKEY_ID_PKCS7 2 - -static char magic_number[] = "~Module signature appended~\n"; +#include static __attribute__((noreturn)) void format(void) @@ -197,7 +185,7 @@ static X509 *read_x509(const char *x509_name) int main(int argc, char **argv) { - struct module_signature sig_info = { .id_type = PKEY_ID_PKCS7 }; + struct module_signature sig_info = { .id_type = MODULE_SIGNATURE_TYPE_PKCS7 }; char *hash_algo = NULL; char *private_key_name = NULL, *raw_sig_name = NULL; char *x509_name, *module_name, *dest_name; @@ -357,7 +345,8 @@ int main(int argc, char **argv) sig_size = BIO_number_written(bd) - module_size; sig_info.sig_len = htonl(sig_size); ERR(BIO_write(bd, &sig_info, sizeof(sig_info)) < 0, "%s", dest_name); - ERR(BIO_write(bd, magic_number, sizeof(magic_number) - 1) < 0, "%s", dest_name); + ERR(BIO_write(bd, MODULE_SIGNATURE_MARKER, sizeof(MODULE_SIGNATURE_MARKER) - 1) < 0, + "%s", dest_name); ERR(BIO_free(bd) != 1, "%s", dest_name); -- cgit v1.2.3 From 9743311b4535dc76ce81f46303da0f69bfaa5fd6 Mon Sep 17 00:00:00 2001 From: Siddharth Nayyar Date: Thu, 26 Mar 2026 21:25:03 +0000 Subject: module: add kflagstab section to vmlinux and modules This patch introduces a __kflagstab section to store symbol flags in a dedicated data structure, similar to how CRCs are handled in the __kcrctab. The flags for a given symbol in __kflagstab will be located at the same index as the symbol's entry in __ksymtab and its CRC in __kcrctab. This design decouples the flags from the symbol table itself, allowing us to maintain a single, sorted __ksymtab. As a result, the symbol search remains an efficient, single lookup, regardless of the number of flags we add in the future. The motivation for this change comes from the Android kernel, which uses an additional symbol flag to restrict the use of certain exported symbols by unsigned modules, thereby enhancing kernel security. This __kflagstab can be implemented as a bitmap to efficiently manage which symbols are available for general use versus those restricted to signed modules only. This section will contain read-only data for values of kernel symbol flags in the form of an 8-bit bitsets for each kernel symbol. Each bit in the bitset represents a flag value defined by ksym_flags enumeration. Petr Pavlu ran a small test to get a better understanding of the different section sizes resulting from this patch series. He used v6.17-rc6 together with the openSUSE x86_64 config [1], which is fairly large. The resulting vmlinux.bin (no debuginfo) had an on-disk size of 58 MiB, and included 5937 + 6589 (GPL-only) exported symbols. The following table summarizes his measurements and calculations regarding the sizes of all sections related to exported symbols: | HAVE_ARCH_PREL32_RELOCATIONS | !HAVE_ARCH_PREL32_RELOCATIONS Section | Base [B] | Ext. [B] | Sep. [B] | Base [B] | Ext. [B] | Sep. [B] ---------------------------------------------------------------------------------------- __ksymtab | 71244 | 200416 | 150312 | 142488 | 400832 | 300624 __ksymtab_gpl | 79068 | NA | NA | 158136 | NA | NA __kcrctab | 23748 | 50104 | 50104 | 23748 | 50104 | 50104 __kcrctab_gpl | 26356 | NA | NA | 26356 | NA | NA __ksymtab_strings | 253628 | 253628 | 253628 | 253628 | 253628 | 253628 __kflagstab | NA | NA | 12526 | NA | NA | 12526 ---------------------------------------------------------------------------------------- Total | 454044 | 504148 | 466570 | 604356 | 704564 | 616882 Increase to base [%] | NA | 11.0 | 2.8 | NA | 16.6 | 2.1 The column "HAVE_ARCH_PREL32_RELOCATIONS -> Base" contains the measured numbers. The rest of the values are calculated. The "Ext." column represents an alternative approach of extending __ksymtab to include a bitset of symbol flags, and the "Sep." column represents the approach of having a separate __kflagstab. With HAVE_ARCH_PREL32_RELOCATIONS, each kernel_symbol is 12 B in size and is extended to 16 B. With !HAVE_ARCH_PREL32_RELOCATIONS, it is 24 B, extended to 32 B. Note that this does not include the metadata needed to relocate __ksymtab*, which is freed after the initial processing. Adding __kflagstab as a separate section has a negligible impact, as expected. When extending __ksymtab (kernel_symbol) instead, the worst case with !HAVE_ARCH_PREL32_RELOCATIONS increases the export data size by 16.6%. Note that the larger increase in size for the latter approach is due to 4-byte alignment of kernel_symbol data structure, instead of 1-byte alignment for the flags bitset in __kflagstab in the former approach. Based on the above, it was concluded that introducing __kflagstab makes sense, as the added complexity is minimal over extending kernel_symbol, and there is overall simplification of symbol finding logic in the module loader. Signed-off-by: Siddharth Nayyar Reviewed-by: Petr Pavlu [Sami: Updated commit message to include details from the cover letter.] Signed-off-by: Sami Tolvanen --- scripts/module.lds.S | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/module.lds.S b/scripts/module.lds.S index e1cab3cee3f7..3ecfb3ea1cc8 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -23,6 +23,7 @@ SECTIONS { __ksymtab_gpl 0 : ALIGN(8) { *(SORT(___ksymtab_gpl+*)) } __kcrctab 0 : ALIGN(4) { *(SORT(___kcrctab+*)) } __kcrctab_gpl 0 : ALIGN(4) { *(SORT(___kcrctab_gpl+*)) } + __kflagstab 0 : ALIGN(1) { *(SORT(___kflagstab+*)) } .ctors 0 : ALIGN(8) { *(SORT(.ctors.*)) *(.ctors) } .init_array 0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) } -- cgit v1.2.3 From 16d0e04f546ffba78c74bbfeb57d93147bcaf2c5 Mon Sep 17 00:00:00 2001 From: Siddharth Nayyar Date: Thu, 26 Mar 2026 21:25:04 +0000 Subject: module: populate kflagstab in modpost This patch adds the ability to create entries for kernel symbol flag bitsets in kflagstab. Modpost populates only the GPL-only flag for now. Signed-off-by: Siddharth Nayyar Reviewed-by: Petr Pavlu Signed-off-by: Sami Tolvanen --- scripts/mod/modpost.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 0c25b5ad497b..1d721fe67caf 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -244,6 +244,11 @@ static struct symbol *alloc_symbol(const char *name) return s; } +static uint8_t get_symbol_flags(const struct symbol *sym) +{ + return sym->is_gpl_only ? KSYM_FLAG_GPL_ONLY : 0; +} + /* For the hash of exported symbols */ static void hash_add_symbol(struct symbol *sym) { @@ -1874,6 +1879,9 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod) buf_printf(buf, "KSYMTAB_%s(%s, \"%s\", \"%s\");\n", sym->is_func ? "FUNC" : "DATA", sym->name, sym->is_gpl_only ? "_gpl" : "", sym->namespace); + + buf_printf(buf, "SYMBOL_FLAGS(%s, 0x%02x);\n", + sym->name, get_symbol_flags(sym)); } if (!modversions) -- cgit v1.2.3 From 55fcb926b6d8b5cfb40873e4840a69961db1bb69 Mon Sep 17 00:00:00 2001 From: Siddharth Nayyar Date: Thu, 26 Mar 2026 21:25:05 +0000 Subject: module: use kflagstab instead of *_gpl sections Read kflagstab section for vmlinux and modules to determine whether kernel symbols are GPL only. This patch eliminates the need for fragmenting the ksymtab for infering the value of GPL-only symbol flag, henceforth stop populating *_gpl versions of the ksymtab and kcrctab in modpost. Signed-off-by: Siddharth Nayyar Reviewed-by: Petr Pavlu Signed-off-by: Sami Tolvanen --- scripts/mod/modpost.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 1d721fe67caf..9d96acce60a8 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1876,9 +1876,9 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod) if (trim_unused_exports && !sym->used) continue; - buf_printf(buf, "KSYMTAB_%s(%s, \"%s\", \"%s\");\n", + buf_printf(buf, "KSYMTAB_%s(%s, \"%s\");\n", sym->is_func ? "FUNC" : "DATA", sym->name, - sym->is_gpl_only ? "_gpl" : "", sym->namespace); + sym->namespace); buf_printf(buf, "SYMBOL_FLAGS(%s, 0x%02x);\n", sym->name, get_symbol_flags(sym)); @@ -1899,8 +1899,8 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod) sym->name, mod->name, mod->is_vmlinux ? "" : ".ko", sym->name); - buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x, \"%s\");\n", - sym->name, sym->crc, sym->is_gpl_only ? "_gpl" : ""); + buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x);\n", + sym->name, sym->crc); } } -- cgit v1.2.3 From f18540256b70c9e1f0e26e2c38f3d43a131926d9 Mon Sep 17 00:00:00 2001 From: Siddharth Nayyar Date: Thu, 26 Mar 2026 21:25:07 +0000 Subject: module: remove *_gpl sections from vmlinux and modules These sections are not used anymore and can be removed from vmlinux and modules during linking. Signed-off-by: Siddharth Nayyar Reviewed-by: Petr Pavlu Signed-off-by: Sami Tolvanen --- scripts/module.lds.S | 2 -- 1 file changed, 2 deletions(-) (limited to 'scripts') diff --git a/scripts/module.lds.S b/scripts/module.lds.S index 3ecfb3ea1cc8..2dc4c8c3e667 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -20,9 +20,7 @@ SECTIONS { } __ksymtab 0 : ALIGN(8) { *(SORT(___ksymtab+*)) } - __ksymtab_gpl 0 : ALIGN(8) { *(SORT(___ksymtab_gpl+*)) } __kcrctab 0 : ALIGN(4) { *(SORT(___kcrctab+*)) } - __kcrctab_gpl 0 : ALIGN(4) { *(SORT(___kcrctab_gpl+*)) } __kflagstab 0 : ALIGN(1) { *(SORT(___kflagstab+*)) } .ctors 0 : ALIGN(8) { *(SORT(.ctors.*)) *(.ctors) } -- cgit v1.2.3