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: <aOToOeNGiaFVM0Ds@example.org>
Date: Tue, 7 Oct 2025 12:15:21 +0200
From: Alexey Gladkov <legion@...nel.org>
To: Charles Mirabile <cmirabil@...hat.com>
Cc: da.gomez@...sung.com, linux-kbuild@...r.kernel.org,
	linux-kernel@...r.kernel.org, linux-modules@...r.kernel.org,
	masahiroy@...nel.org, mcgrof@...nel.org, nathan@...nel.org,
	nicolas.schier@...ux.dev, petr.pavlu@...e.com,
	samitolvanen@...gle.com, sfr@...b.auug.org.au
Subject: Re: [PATCH v8 7/8] modpost: Create modalias for builtin modules

On Mon, Oct 06, 2025 at 09:16:37PM -0400, Charles Mirabile wrote:
> On Thu, Sep 18, 2025 at 10:05:51AM +0200, Alexey Gladkov wrote:
> > For some modules, modalias is generated using the modpost utility and
> > the section is added to the module file.
> > 
> > When a module is added inside vmlinux, modpost does not generate
> > modalias for such modules and the information is lost.
> > 
> > As a result kmod (which uses modules.builtin.modinfo in userspace)
> > cannot determine that modalias is handled by a builtin kernel module.
> > 
> > $ cat /sys/devices/pci0000:00/0000:00:14.0/modalias
> > pci:v00008086d0000A36Dsv00001043sd00008694bc0Csc03i30
> > 
> > $ modinfo xhci_pci
> > name:           xhci_pci
> > filename:       (builtin)
> > license:        GPL
> > file:           drivers/usb/host/xhci-pci
> > description:    xHCI PCI Host Controller Driver
> > 
> > Missing modalias "pci:v*d*sv*sd*bc0Csc03i30*" which will be generated by
> > modpost if the module is built separately.
> > 
> > To fix this it is necessary to generate the same modalias for vmlinux as
> > for the individual modules. Fortunately '.vmlinux.export.o' is already
> > generated from which '.modinfo' can be extracted in the same way as for
> > vmlinux.o.
> 
> Hi -
> 
> This patch broke RISC-V builds for me. During the final objcopy where the new
> symbols are supposed to be stripped, an error occurs producing lots of error
> messages similar to this one:
> 
> riscv64-linux-gnu-objcopy: not stripping symbol `__mod_device_table__...'
> because it is named in a relocation
> 
> It does not occur using defconfig, but I was able to bisect my way to this
> commit and then reduce my config delta w.r.t defconfig until I landed on:
> 
> cat > .config <<'EOF'
> CONFIG_RELOCATABLE=y
> CONFIG_KASAN=y
> EOF
> ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- make olddefconfig
> ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- make -j $(nproc)
> ...
>   LD      vmlinux.unstripped
>   NM      System.map
>   SORTTAB vmlinux.unstripped
>   CHKREL  vmlinux.unstripped
>   OBJCOPY vmlinux
>   OBJCOPY modules.builtin.modinfo
>   GEN     modules.builtin
> riscv64-linux-gnu-objcopy: not stripping symbol `<long symbol name>'
> because it is named in a relocation
> <repeats with different symbol names about a dozen times>
> make[3]: *** [scripts/Makefile.vmlinux:97: vmlinux] Error 1
> make[3]: *** Deleting file 'vmlinux'
> make[2]: *** [Makefile:1242: vmlinux] Error 2
> make[1]: *** [/tmp/linux/Makefile:369: __build_one_by_one] Error 2
> make: *** [Makefile:248: __sub-make] Error 2
> 
> I confirmed that reverting this commit fixes the issue.

Hm. Indeed. I haven't found a good solution yet, but you can use the
following patch to unlock compilation. It won't solve the problem, it will
only hide it.

--- a/scripts/Makefile.vmlinux
+++ b/scripts/Makefile.vmlinux
@@ -84,7 +84,7 @@ endif
 remove-section-y                                   := .modinfo
 remove-section-$(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS) += '.rel*'

-remove-symbols := -w --strip-symbol='__mod_device_table__*'
+remove-symbols := -w --strip-unneeded-symbol='__mod_device_table__*'

 # To avoid warnings: "empty loadable segment detected at ..." from GNU objcopy,
 # it is necessary to remove the PT_LOAD flag from the segment.

> > 
> > Signed-off-by: Masahiro Yamada <masahiroy@...nel.org>
> > Signed-off-by: Alexey Gladkov <legion@...nel.org>
> > Tested-by: Stephen Rothwell <sfr@...b.auug.org.au>
> > ---
> >  include/linux/module.h   |  4 ----
> >  scripts/Makefile.vmlinux |  4 +++-
> >  scripts/mksysmap         |  3 +++
> >  scripts/mod/file2alias.c | 19 ++++++++++++++++++-
> >  scripts/mod/modpost.c    | 15 +++++++++++++++
> >  scripts/mod/modpost.h    |  2 ++
> >  6 files changed, 41 insertions(+), 6 deletions(-)
> > 
> > diff --git a/include/linux/module.h b/include/linux/module.h
> > index e31ee29fac6b7..e135cc79aceea 100644
> > --- a/include/linux/module.h
> > +++ b/include/linux/module.h
> > @@ -256,14 +256,10 @@ struct module_kobject *lookup_or_create_module_kobject(const char *name);
> >  	__PASTE(type,			\
> >  	__PASTE(__, name)))))
> >  
> > -#ifdef MODULE
> >  /* Creates an alias so file2alias.c can find device table. */
> >  #define MODULE_DEVICE_TABLE(type, name)					\
> >  static typeof(name) __mod_device_table(type, name)			\
> >    __attribute__ ((used, alias(__stringify(name))))
> > -#else  /* !MODULE */
> > -#define MODULE_DEVICE_TABLE(type, name)
> > -#endif
> >  
> >  /* Version of form [<epoch>:]<version>[-<extra-version>].
> >   * Or for CVS/RCS ID version, everything but the number is stripped.
> > diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux
> > index ce79461714979..1e5e37aadcd05 100644
> > --- a/scripts/Makefile.vmlinux
> > +++ b/scripts/Makefile.vmlinux
> > @@ -89,11 +89,13 @@ endif
> >  remove-section-y                                   := .modinfo
> >  remove-section-$(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS) += '.rel*'
> >  
> > +remove-symbols := -w --strip-symbol='__mod_device_table__*'
> > +
> >  # To avoid warnings: "empty loadable segment detected at ..." from GNU objcopy,
> >  # it is necessary to remove the PT_LOAD flag from the segment.
> >  quiet_cmd_strip_relocs = OBJCOPY $@
> >        cmd_strip_relocs = $(OBJCOPY) $(patsubst %,--set-section-flags %=noload,$(remove-section-y)) $< $@; \
> > -                         $(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) $@
> > +                         $(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) $(remove-symbols) $@
> >  
> >  targets += vmlinux
> >  vmlinux: vmlinux.unstripped FORCE
> > diff --git a/scripts/mksysmap b/scripts/mksysmap
> > index a607a0059d119..c4531eacde202 100755
> > --- a/scripts/mksysmap
> > +++ b/scripts/mksysmap
> > @@ -59,6 +59,9 @@
> >  # EXPORT_SYMBOL (namespace)
> >  / __kstrtabns_/d
> >  
> > +# MODULE_DEVICE_TABLE (symbol name)
> > +/ __mod_device_table__/d
> > +
> >  # ---------------------------------------------------------------------------
> >  # Ignored suffixes
> >  #  (do not forget '$' after each pattern)
> > diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
> > index 1260bc2287fba..7da9735e7ab3e 100644
> > --- a/scripts/mod/file2alias.c
> > +++ b/scripts/mod/file2alias.c
> > @@ -1477,7 +1477,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
> >  	void *symval;
> >  	char *zeros = NULL;
> >  	const char *type, *name, *modname;
> > -	size_t typelen;
> > +	size_t typelen, modnamelen;
> >  	static const char *prefix = "__mod_device_table__";
> >  
> >  	/* We're looking for a section relative symbol */
> > @@ -1500,6 +1500,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
> >  	type = strstr(modname, "__");
> >  	if (!type)
> >  		return;
> > +	modnamelen = type - modname;
> >  	type += strlen("__");
> >  
> >  	name = strstr(type, "__");
> > @@ -1526,5 +1527,21 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
> >  		}
> >  	}
> >  
> > +	if (mod->is_vmlinux) {
> > +		struct module_alias *alias;
> > +
> > +		/*
> > +		 * If this is vmlinux, record the name of the builtin module.
> > +		 * Traverse the linked list in the reverse order, and set the
> > +		 * builtin_modname unless it has already been set in the
> > +		 * previous call.
> > +		 */
> > +		list_for_each_entry_reverse(alias, &mod->aliases, node) {
> > +			if (alias->builtin_modname)
> > +				break;
> > +			alias->builtin_modname = xstrndup(modname, modnamelen);
> > +		}
> > +	}
> > +
> >  	free(zeros);
> >  }
> > diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> > index 5ca7c268294eb..47c8aa2a69392 100644
> > --- a/scripts/mod/modpost.c
> > +++ b/scripts/mod/modpost.c
> > @@ -2067,11 +2067,26 @@ static void write_if_changed(struct buffer *b, const char *fname)
> >  static void write_vmlinux_export_c_file(struct module *mod)
> >  {
> >  	struct buffer buf = { };
> > +	struct module_alias *alias, *next;
> >  
> >  	buf_printf(&buf,
> >  		   "#include <linux/export-internal.h>\n");
> >  
> >  	add_exported_symbols(&buf, mod);
> > +
> > +	buf_printf(&buf,
> > +		   "#include <linux/module.h>\n"
> > +		   "#undef __MODULE_INFO_PREFIX\n"
> > +		   "#define __MODULE_INFO_PREFIX\n");
> > +
> > +	list_for_each_entry_safe(alias, next, &mod->aliases, node) {
> > +		buf_printf(&buf, "MODULE_INFO(%s.alias, \"%s\");\n",
> > +			   alias->builtin_modname, alias->str);
> > +		list_del(&alias->node);
> > +		free(alias->builtin_modname);
> > +		free(alias);
> > +	}
> > +
> >  	write_if_changed(&buf, ".vmlinux.export.c");
> >  	free(buf.p);
> >  }
> > diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
> > index 9133e4c3803f0..2aecb8f25c87e 100644
> > --- a/scripts/mod/modpost.h
> > +++ b/scripts/mod/modpost.h
> > @@ -99,10 +99,12 @@ buf_write(struct buffer *buf, const char *s, int len);
> >   * struct module_alias - auto-generated MODULE_ALIAS()
> >   *
> >   * @node: linked to module::aliases
> > + * @modname: name of the builtin module (only for vmlinux)
> >   * @str: a string for MODULE_ALIAS()
> >   */
> >  struct module_alias {
> >  	struct list_head node;
> > +	char *builtin_modname;
> >  	char str[];
> >  };
> >  
> > -- 
> > 2.51.0
> > 
> 

-- 
Rgrds, legion


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ