* [PATCH v6 0/5] Extended MODVERSIONS Support
@ 2024-10-15 23:18 Matthew Maurer
2024-10-15 23:18 ` [PATCH v6 1/5] export_report: Rehabilitate script Matthew Maurer
` (4 more replies)
0 siblings, 5 replies; 13+ messages in thread
From: Matthew Maurer @ 2024-10-15 23:18 UTC (permalink / raw)
To: masahiroy, ndesaulniers, ojeda, gary, mcgrof, Alex Gaynor
Cc: rust-for-linux, linux-kbuild, linux-kernel, neal, marcan, j,
asahi, linux-modules, samitolvanen, Matthew Maurer, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross
This patch series is intended for use alongside the Implement
MODVERSIONS for RUST [1] series as a replacement for the symbol name
hashing approach used there to enable RUST and MODVERSIONS at the same
time.
Elsewhere, we've seen a desire for long symbol name support for LTO
symbol names [2], and the previous series came up [3] as a possible
solution rather than hashing, which some have objected [4] to.
This series adds a MODVERSIONS format which uses a section per column.
This avoids userspace tools breaking if we need to make a similar change
to the format in the future - we would do so by adding a new section,
rather than editing the struct definition. In the new format, the name
section is formatted as a concatenated sequence of NUL-terminated
strings, which allows for arbitrary length names.
Emitting the extended format is guarded by CONFIG_EXTENDED_MODVERSIONS,
but the kernel always knows how to validate both the original and
extended formats.
If you are testing this patch alongside RUST by manually removing the
!MODVERSIONS restriction (this series doesn't remove it, because the
CRCs don't mean what we'd want them to yet, we need the DWARF patch for
that) and have kernel hardening enabled, you may need the CPU
Mitigations [5] series. Without it, the foo.mod.o file produced by the
C compiler will reference __x86_return_thunk, but foo.o will not.
This means that the version table will not contain a version for
__x86_return_thunk, but foo.ko will reference it, which will result
in a version check failure.
This series depends upon the module verification refactor patches [6]
that were split off of v5.
[1] https://lore.kernel.org/all/20240617175818.58219-17-samitolvanen@google.com/
[2] https://lore.kernel.org/lkml/20240605032120.3179157-1-song@kernel.org/
[3] https://lore.kernel.org/lkml/ZoxbEEsK40ASi1cY@bombadil.infradead.org/
[4] https://lore.kernel.org/lkml/0b2697fd-7ab4-469f-83a6-ec9ebc701ba0@suse.com/
[5] https://lore.kernel.org/all/20240725183325.122827-1-ojeda@kernel.org/
[6] https://lore.kernel.org/linux-modules/20241015231651.3851138-1-mmaurer@google.com/T/#t
Changes in v6:
- Splits verification refactor Luis requested out to a separate change
- Clarifies commits around export_report.pl repairs
- Add CONFIG_EXTENDED_MODVERSIONS to control whether extended
information is included in the module, per Luis's request.
v5: https://lore.kernel.org/all/20240925233854.90072-1-mmaurer@google.com/
- Addresses Sami's comments from v3 that I missed in v4 (missing early
return, extra parens)
v4: https://lore.kernel.org/asahi/20240924212024.540574-1-mmaurer@google.com/
- Fix incorrect dot munging in PPC
v3: https://lore.kernel.org/lkml/87le0w2hop.fsf@mail.lhotse/T/
- Split up the module verification refactor into smaller patches, per
Greg K-H's suggestion.
v2: https://lore.kernel.org/all/20231118025748.2778044-1-mmaurer@google.com/
- Add loading/verification refactor before modifying, per Luis's request
v1: https://lore.kernel.org/rust-for-linux/20231115185858.2110875-1-mmaurer@google.com/
Matthew Maurer (5):
export_report: Rehabilitate script
modules: Support extended MODVERSIONS info
export_report: Tolerate additional `.mod.c` content
modpost: Produce extended MODVERSIONS information
export_report: Use new version info format
arch/powerpc/kernel/module_64.c | 23 ++++++++-
kernel/module/Kconfig | 8 +++
kernel/module/internal.h | 11 ++++
kernel/module/main.c | 92 ++++++++++++++++++++++++++++++---
kernel/module/version.c | 45 ++++++++++++++++
scripts/export_report.pl | 17 +++---
scripts/mod/modpost.c | 41 +++++++++++++++
7 files changed, 220 insertions(+), 17 deletions(-)
--
2.47.0.rc1.288.g06298d1525-goog
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v6 1/5] export_report: Rehabilitate script
2024-10-15 23:18 [PATCH v6 0/5] Extended MODVERSIONS Support Matthew Maurer
@ 2024-10-15 23:18 ` Matthew Maurer
2024-10-17 0:29 ` Sami Tolvanen
2024-10-28 13:13 ` Masahiro Yamada
2024-10-15 23:18 ` [PATCH v6 2/5] modules: Support extended MODVERSIONS info Matthew Maurer
` (3 subsequent siblings)
4 siblings, 2 replies; 13+ messages in thread
From: Matthew Maurer @ 2024-10-15 23:18 UTC (permalink / raw)
To: masahiroy, ndesaulniers, ojeda, gary, mcgrof, Alex Gaynor
Cc: rust-for-linux, linux-kbuild, linux-kernel, neal, marcan, j,
asahi, linux-modules, samitolvanen, Matthew Maurer, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross
The `export_report.pl` script was broken [1] a while back due to a code
cleanup causing the regex to no longer match. Additionally, it assumes a
`modules.order` file containing `.ko` in a build directory with `.mod.c`
files. I cannot find when this would have been the case in the history,
as normally `.ko` files only appear in `modules.order` in installed
modules directories, and those do not contain `.mod.c` files.
This patch makes it able to report symbol usage counts for a build tree
with modules and MODVERSIONS.
Since the rest of this series will change the format of `.mod.c`, this
change fixes the script to work correctly against a current build tree.
Given that the regex no longer matches the format used in `.mod.c`, it
cannot have worked since 2019, so updating this script is purely out of
an abundance of caution. I am unsure who uses this script or for what
purpose.
* modules.order in a build directory uses .o, not .ko files. Allow .o
files when parsing modules.order.
* The .mod.c format changed [1] how it expressed the section attribute,
leading to a regex mismatch. Update it to match modpost.c
[1]: https://lore.kernel.org/all/20190909113423.2289-2-yamada.masahiro@socionext.com/
Signed-off-by: Matthew Maurer <mmaurer@google.com>
---
scripts/export_report.pl | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/scripts/export_report.pl b/scripts/export_report.pl
index feb3d5542a62..30b5f7819086 100755
--- a/scripts/export_report.pl
+++ b/scripts/export_report.pl
@@ -55,6 +55,7 @@ sub collectcfiles {
open my $fh, '< modules.order' or die "cannot open modules.order: $!\n";
while (<$fh>) {
s/\.ko$/.mod.c/;
+ s/\.o$/.mod.c/;
push (@file, $_)
}
close($fh);
@@ -120,7 +121,7 @@ foreach my $thismod (@allcfiles) {
next;
}
if ($state == 1) {
- $state = 2 if ($_ =~ /__attribute__\(\(section\("__versions"\)\)\)/);
+ $state = 2 if ($_ =~ /__used __section\("__versions"\)/);
next;
}
if ($state == 2) {
--
2.47.0.rc1.288.g06298d1525-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v6 2/5] modules: Support extended MODVERSIONS info
2024-10-15 23:18 [PATCH v6 0/5] Extended MODVERSIONS Support Matthew Maurer
2024-10-15 23:18 ` [PATCH v6 1/5] export_report: Rehabilitate script Matthew Maurer
@ 2024-10-15 23:18 ` Matthew Maurer
2024-10-21 18:44 ` Luis Chamberlain
2024-10-15 23:18 ` [PATCH v6 3/5] export_report: Tolerate additional `.mod.c` content Matthew Maurer
` (2 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Matthew Maurer @ 2024-10-15 23:18 UTC (permalink / raw)
To: masahiroy, ndesaulniers, ojeda, gary, mcgrof, Michael Ellerman,
Alex Gaynor, Naveen N Rao, Arnd Bergmann,
Mike Rapoport (Microsoft), Benjamin Gray
Cc: rust-for-linux, linux-kbuild, linux-kernel, neal, marcan, j,
asahi, linux-modules, samitolvanen, Matthew Maurer,
Nicholas Piggin, Christophe Leroy, Madhavan Srinivasan,
Petr Pavlu, Daniel Gomez, Boqun Feng, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Andrew Morton, linuxppc-dev
Adds a new format for MODVERSIONS which stores each field in a separate
ELF section. This initially adds support for variable length names, but
could later be used to add additional fields to MODVERSIONS in a
backwards compatible way if needed. Any new fields will be ignored by
old user tooling, unlike the current format where user tooling cannot
tolerate adjustments to the format (for example making the name field
longer).
Since PPC munges its version records to strip leading dots, we reproduce
the munging for the new format. Other architectures do not appear to
have architecture-specific usage of this information.
Signed-off-by: Matthew Maurer <mmaurer@google.com>
---
arch/powerpc/kernel/module_64.c | 23 ++++++++-
kernel/module/internal.h | 11 ++++
kernel/module/main.c | 92 ++++++++++++++++++++++++++++++---
kernel/module/version.c | 45 ++++++++++++++++
4 files changed, 161 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 135960918d14..0f7ef7e7e9d6 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -355,6 +355,23 @@ static void dedotify_versions(struct modversion_info *vers,
}
}
+static void dedotify_ext_version_names(char *str_seq, unsigned long size)
+{
+ unsigned long out = 0;
+ unsigned long in;
+ char last = '\0';
+
+ for (in = 0; in < size; in++) {
+ /* Skip one leading dot */
+ if (last == '\0' && str_seq[in] == '.')
+ in++;
+ last = str_seq[in];
+ str_seq[out++] = last;
+ }
+ /* Zero the trailing portion of the names table for robustness */
+ memset(&str_seq[out], 0, size - out);
+}
+
/*
* Undefined symbols which refer to .funcname, hack to funcname. Make .TOC.
* seem to be defined (value set later).
@@ -424,10 +441,12 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
me->arch.toc_section = i;
if (sechdrs[i].sh_addralign < 8)
sechdrs[i].sh_addralign = 8;
- }
- else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0)
+ } else if (strcmp(secstrings + sechdrs[i].sh_name, "__versions") == 0)
dedotify_versions((void *)hdr + sechdrs[i].sh_offset,
sechdrs[i].sh_size);
+ else if (strcmp(secstrings + sechdrs[i].sh_name, "__version_ext_names") == 0)
+ dedotify_ext_version_names((void *)hdr + sechdrs[i].sh_offset,
+ sechdrs[i].sh_size);
if (sechdrs[i].sh_type == SHT_SYMTAB)
dedotify((void *)hdr + sechdrs[i].sh_offset,
diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index daef2be83902..59959c21b205 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -86,6 +86,8 @@ struct load_info {
unsigned int vers;
unsigned int info;
unsigned int pcpu;
+ unsigned int vers_ext_crc;
+ unsigned int vers_ext_name;
} index;
};
@@ -389,6 +391,15 @@ void module_layout(struct module *mod, struct modversion_info *ver, struct kerne
struct kernel_symbol *ks, struct tracepoint * const *tp);
int check_modstruct_version(const struct load_info *info, struct module *mod);
int same_magic(const char *amagic, const char *bmagic, bool has_crcs);
+struct modversion_info_ext {
+ size_t remaining;
+ const s32 *crc;
+ const char *name;
+};
+void modversion_ext_start(const struct load_info *info, struct modversion_info_ext *ver);
+void modversion_ext_advance(struct modversion_info_ext *ver);
+#define for_each_modversion_info_ext(ver, info) \
+ for (modversion_ext_start(info, &ver); ver.remaining > 0; modversion_ext_advance(&ver))
#else /* !CONFIG_MODVERSIONS */
static inline int check_version(const struct load_info *info,
const char *symname,
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 3db9ff544c09..f5f4ceaef31a 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -2072,6 +2072,82 @@ static int elf_validity_cache_index_str(struct load_info *info)
return 0;
}
+/**
+ * elf_validity_cache_index_versions() - Validate and cache version indices
+ * @info: Load info to cache version indices in.
+ * Must have &load_info->sechdrs and &load_info->secstrings populated.
+ * @flags: Load flags, relevant to suppress version loading, see
+ * uapi/linux/module.h
+ *
+ * If we're ignoring modversions based on @flags, zero all version indices
+ * and return validity. Othewrise check:
+ *
+ * * If "__version_ext_crcs" is present, "__version_ext_names" is present
+ * * There is a name present for every crc
+ *
+ * Then populate:
+ *
+ * * &load_info->index.vers
+ * * &load_info->index.vers_ext_crc
+ * * &load_info->index.vers_ext_names
+ *
+ * if present.
+ *
+ * Return: %0 if valid, %-ENOEXEC on failure.
+ */
+static int elf_validity_cache_index_versions(struct load_info *info, int flags)
+{
+ unsigned int vers_ext_crc;
+ unsigned int vers_ext_name;
+ size_t crc_count;
+ size_t remaining_len;
+ size_t name_size;
+ char *name;
+
+ /* If modversions were suppressed, pretend we didn't find any */
+ if (flags & MODULE_INIT_IGNORE_MODVERSIONS) {
+ info->index.vers = 0;
+ info->index.vers_ext_crc = 0;
+ info->index.vers_ext_name = 0;
+ return 0;
+ }
+
+ vers_ext_crc = find_sec(info, "__version_ext_crcs");
+ vers_ext_name = find_sec(info, "__version_ext_names");
+
+ /* If we have one field, we must have the other */
+ if (!!vers_ext_crc != !!vers_ext_name) {
+ pr_err("extended version crc+name presence does not match");
+ return -ENOEXEC;
+ }
+
+ /*
+ * If we have extended version information, we should have the same
+ * number of entries in every section.
+ */
+ if (vers_ext_crc) {
+ crc_count = info->sechdrs[vers_ext_crc].sh_size / sizeof(s32);
+ name = (void *)info->hdr +
+ info->sechdrs[vers_ext_name].sh_offset;
+ remaining_len = info->sechdrs[vers_ext_name].sh_size;
+
+ while (crc_count--) {
+ name_size = strnlen(name, remaining_len) + 1;
+ if (name_size > remaining_len) {
+ pr_err("more extended version crcs than names");
+ return -ENOEXEC;
+ }
+ remaining_len -= name_size;
+ name += name_size;
+ }
+ }
+
+ info->index.vers = find_sec(info, "__versions");
+ info->index.vers_ext_crc = vers_ext_crc;
+ info->index.vers_ext_name = vers_ext_name;
+ return 0;
+}
+
/**
* elf_validity_cache_index() - Resolve, validate, cache section indices
* @info: Load info to read from and update.
@@ -2086,9 +2162,7 @@ static int elf_validity_cache_index_str(struct load_info *info)
* * elf_validity_cache_index_mod()
* * elf_validity_cache_index_sym()
* * elf_validity_cache_index_str()
- *
- * If versioning is not suppressed via flags, load the version index from
- * a section called "__versions" with no validation.
+ * * elf_validity_cache_index_versions()
*
* If CONFIG_SMP is enabled, load the percpu section by name with no
* validation.
@@ -2111,11 +2185,9 @@ static int elf_validity_cache_index(struct load_info *info, int flags)
err = elf_validity_cache_index_str(info);
if (err < 0)
return err;
-
- if (flags & MODULE_INIT_IGNORE_MODVERSIONS)
- info->index.vers = 0; /* Pretend no __versions section! */
- else
- info->index.vers = find_sec(info, "__versions");
+ err = elf_validity_cache_index_versions(info, flags);
+ if (err < 0)
+ return err;
info->index.pcpu = find_pcpusec(info);
@@ -2326,6 +2398,10 @@ static int rewrite_section_headers(struct load_info *info, int flags)
/* Track but don't keep modinfo and version sections. */
info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC;
+ info->sechdrs[info->index.vers_ext_crc].sh_flags &=
+ ~(unsigned long)SHF_ALLOC;
+ info->sechdrs[info->index.vers_ext_name].sh_flags &=
+ ~(unsigned long)SHF_ALLOC;
info->sechdrs[info->index.info].sh_flags &= ~(unsigned long)SHF_ALLOC;
return 0;
diff --git a/kernel/module/version.c b/kernel/module/version.c
index 53f43ac5a73e..c246d4087970 100644
--- a/kernel/module/version.c
+++ b/kernel/module/version.c
@@ -19,11 +19,28 @@ int check_version(const struct load_info *info,
unsigned int versindex = info->index.vers;
unsigned int i, num_versions;
struct modversion_info *versions;
+ struct modversion_info_ext version_ext;
/* Exporting module didn't supply crcs? OK, we're already tainted. */
if (!crc)
return 1;
+ /* If we have extended version info, rely on it */
+ if (info->index.vers_ext_crc) {
+ for_each_modversion_info_ext(version_ext, info) {
+ if (strcmp(version_ext.name, symname) != 0)
+ continue;
+ if (*version_ext.crc == *crc)
+ return 1;
+ pr_debug("Found checksum %X vs module %X\n",
+ *crc, *version_ext.crc);
+ goto bad_version;
+ }
+ pr_warn_once("%s: no extended symbol version for %s\n",
+ info->name, symname);
+ return 1;
+ }
+
/* No versions at all? modprobe --force does this. */
if (versindex == 0)
return try_to_force_load(mod, symname) == 0;
@@ -87,6 +104,34 @@ int same_magic(const char *amagic, const char *bmagic,
return strcmp(amagic, bmagic) == 0;
}
+void modversion_ext_start(const struct load_info *info,
+ struct modversion_info_ext *start)
+{
+ unsigned int crc_idx = info->index.vers_ext_crc;
+ unsigned int name_idx = info->index.vers_ext_name;
+ Elf_Shdr *sechdrs = info->sechdrs;
+
+ /*
+ * Both of these fields are needed for this to be useful
+ * Any future fields should be initialized to NULL if absent.
+ */
+ if (crc_idx == 0 || name_idx == 0) {
+ start->remaining = 0;
+ return;
+ }
+
+ start->crc = (const s32 *)sechdrs[crc_idx].sh_addr;
+ start->name = (const char *)sechdrs[name_idx].sh_addr;
+ start->remaining = sechdrs[crc_idx].sh_size / sizeof(*start->crc);
+}
+
+void modversion_ext_advance(struct modversion_info_ext *vers)
+{
+ vers->remaining--;
+ vers->crc++;
+ vers->name += strlen(vers->name) + 1;
+}
+
/*
* Generate the signature for all relevant module structures here.
* If these change, we don't want to try to parse the module.
--
2.47.0.rc1.288.g06298d1525-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v6 3/5] export_report: Tolerate additional `.mod.c` content
2024-10-15 23:18 [PATCH v6 0/5] Extended MODVERSIONS Support Matthew Maurer
2024-10-15 23:18 ` [PATCH v6 1/5] export_report: Rehabilitate script Matthew Maurer
2024-10-15 23:18 ` [PATCH v6 2/5] modules: Support extended MODVERSIONS info Matthew Maurer
@ 2024-10-15 23:18 ` Matthew Maurer
2024-10-15 23:18 ` [PATCH v6 4/5] modpost: Produce extended MODVERSIONS information Matthew Maurer
2024-10-15 23:19 ` [PATCH v6 5/5] export_report: Use new version info format Matthew Maurer
4 siblings, 0 replies; 13+ messages in thread
From: Matthew Maurer @ 2024-10-15 23:18 UTC (permalink / raw)
To: masahiroy, ndesaulniers, ojeda, gary, mcgrof, Alex Gaynor
Cc: rust-for-linux, linux-kbuild, linux-kernel, neal, marcan, j,
asahi, linux-modules, samitolvanen, Matthew Maurer, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross
Currently, `export_report.pl` will error out if it sees a hex number not
in the context of the original `__versions` array. This adds a
"finished" state so that it does not attempt to parse content past the
end of the array, and requires the array to be terminated.
This is prepwork for the subsequent extended modversions information,
which would not be parseable otherwise.
Signed-off-by: Matthew Maurer <mmaurer@google.com>
---
scripts/export_report.pl | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/scripts/export_report.pl b/scripts/export_report.pl
index 30b5f7819086..dcef915405f3 100755
--- a/scripts/export_report.pl
+++ b/scripts/export_report.pl
@@ -125,6 +125,10 @@ foreach my $thismod (@allcfiles) {
next;
}
if ($state == 2) {
+ if ( $_ =~ /};/ ) {
+ $state = 3;
+ next;
+ }
if ( $_ !~ /0x[0-9a-f]+,/ ) {
next;
}
@@ -134,7 +138,7 @@ foreach my $thismod (@allcfiles) {
push(@{$MODULE{$thismod}} , $sym);
}
}
- if ($state != 2) {
+ if ($state != 3) {
warn "WARNING:$thismod is not built with CONFIG_MODVERSIONS enabled\n";
$modversion_warnings++;
}
--
2.47.0.rc1.288.g06298d1525-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v6 4/5] modpost: Produce extended MODVERSIONS information
2024-10-15 23:18 [PATCH v6 0/5] Extended MODVERSIONS Support Matthew Maurer
` (2 preceding siblings ...)
2024-10-15 23:18 ` [PATCH v6 3/5] export_report: Tolerate additional `.mod.c` content Matthew Maurer
@ 2024-10-15 23:18 ` Matthew Maurer
2024-10-17 0:25 ` Sami Tolvanen
` (2 more replies)
2024-10-15 23:19 ` [PATCH v6 5/5] export_report: Use new version info format Matthew Maurer
4 siblings, 3 replies; 13+ messages in thread
From: Matthew Maurer @ 2024-10-15 23:18 UTC (permalink / raw)
To: masahiroy, ndesaulniers, ojeda, gary, mcgrof, Alex Gaynor
Cc: rust-for-linux, linux-kbuild, linux-kernel, neal, marcan, j,
asahi, linux-modules, samitolvanen, Matthew Maurer, Petr Pavlu,
Daniel Gomez, Nathan Chancellor, Nicolas Schier, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross
Generate both the existing modversions format and the new extended one
when running modpost. Presence of this metadata in the final .ko is
guarded by CONFIG_EXTENDED_MODVERSIONS.
We no longer generate an error on long symbols in modpost if
CONFIG_EXTENDED_MODVERSIONS is set, as they can now be appropriately
encoded in the extended section. These symbols will be skipped in the
previous encoding. An error will still be generated if
CONFIG_EXTENDED_MODVERSIONS is not set.
Signed-off-by: Matthew Maurer <mmaurer@google.com>
---
kernel/module/Kconfig | 8 ++++++++
scripts/mod/modpost.c | 41 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+)
diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig
index 7c6588148d42..a5de2b7f2758 100644
--- a/kernel/module/Kconfig
+++ b/kernel/module/Kconfig
@@ -177,6 +177,14 @@ config ASM_MODVERSIONS
assembly. This can be enabled only when the target architecture
supports it.
+config EXTENDED_MODVERSIONS
+ bool "Extended Module Versioning Support"
+ depends on MODVERSIONS
+ help
+ This enables extended MODVERSIONs support, allowing long symbol
+ names to be versioned. The most likely reasons you would enable
+ this are for Rust usage or aggressive LTO configurations.
+
config MODULE_SRCVERSION_ALL
bool "Source checksum for all modules"
help
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 107393a8c48a..d18ff8a1109a 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1840,15 +1840,56 @@ static void add_versions(struct buffer *b, struct module *mod)
continue;
}
if (strlen(s->name) >= MODULE_NAME_LEN) {
+#ifdef CONFIG_EXTENDED_MODVERSIONS
+ /* this symbol will only be in the extended info */
+ continue;
+#else
error("too long symbol \"%s\" [%s.ko]\n",
s->name, mod->name);
break;
+#endif
}
buf_printf(b, "\t{ %#8x, \"%s\" },\n",
s->crc, s->name);
}
buf_printf(b, "};\n");
+
+ buf_printf(b, "#ifdef CONFIG_EXTENDED_MODVERSIONS\n");
+ buf_printf(b, "static const s32 ____version_ext_crcs[]\n");
+ buf_printf(b, "__used __section(\"__version_ext_crcs\") = {\n");
+ list_for_each_entry(s, &mod->unresolved_symbols, list) {
+ if (!s->module)
+ continue;
+ if (!s->crc_valid) {
+ /*
+ * We already warned on this when producing the legacy
+ * modversions table.
+ */
+ continue;
+ }
+ buf_printf(b, "\t%#8x,\n", s->crc);
+ }
+ buf_printf(b, "};\n");
+
+ buf_printf(b, "static const char ____version_ext_names[]\n");
+ buf_printf(b, "__used __section(\"__version_ext_names\") =\n");
+ list_for_each_entry(s, &mod->unresolved_symbols, list) {
+ if (!s->module)
+ continue;
+ if (!s->crc_valid) {
+ /*
+ * We already warned on this when producing the legacy
+ * modversions table.
+ * We need to skip its name too, as the indexes in
+ * both tables need to align.
+ */
+ continue;
+ }
+ buf_printf(b, "\t\"%s\\0\"\n", s->name);
+ }
+ buf_printf(b, ";\n");
+ buf_printf(b, "#endif\n");
}
static void add_depends(struct buffer *b, struct module *mod)
--
2.47.0.rc1.288.g06298d1525-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v6 5/5] export_report: Use new version info format
2024-10-15 23:18 [PATCH v6 0/5] Extended MODVERSIONS Support Matthew Maurer
` (3 preceding siblings ...)
2024-10-15 23:18 ` [PATCH v6 4/5] modpost: Produce extended MODVERSIONS information Matthew Maurer
@ 2024-10-15 23:19 ` Matthew Maurer
4 siblings, 0 replies; 13+ messages in thread
From: Matthew Maurer @ 2024-10-15 23:19 UTC (permalink / raw)
To: masahiroy, ndesaulniers, ojeda, gary, mcgrof, Alex Gaynor
Cc: rust-for-linux, linux-kbuild, linux-kernel, neal, marcan, j,
asahi, linux-modules, samitolvanen, Matthew Maurer, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross
The new version info format has a superset of symbols in the old format.
Since this is a tool for in-tree modules, we don't need to parse the old
one with this tool any longer.
Even if we build without CONFIG_EXTENDED_MODVERSIONS, these are still in
the `.mod.c` file. Their presence in the final module is controlled by
conditional compilation inside the at file.
Signed-off-by: Matthew Maurer <mmaurer@google.com>
---
scripts/export_report.pl | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/scripts/export_report.pl b/scripts/export_report.pl
index dcef915405f3..6a37df6f947f 100755
--- a/scripts/export_report.pl
+++ b/scripts/export_report.pl
@@ -114,31 +114,29 @@ foreach my $thismod (@allcfiles) {
}
my $state=0;
+ # State map:
+ # 0 - Looking for names
+ # 1 - Scanning names
+ # 2 - Done
while ( <$module> ) {
chomp;
if ($state == 0) {
- $state = 1 if ($_ =~ /static const struct modversion_info/);
+ $state = 1 if ($_ =~ /__used __section\("__version_ext_names"\)/);
next;
}
if ($state == 1) {
- $state = 2 if ($_ =~ /__used __section\("__versions"\)/);
- next;
- }
- if ($state == 2) {
- if ( $_ =~ /};/ ) {
- $state = 3;
- next;
- }
- if ( $_ !~ /0x[0-9a-f]+,/ ) {
+ if ( $_ =~ /;/ ) {
+ $state = 2;
next;
}
- my $sym = (split /([,"])/,)[4];
+ $_ =~ /"(.*)\\0"/;
+ my $sym = $1;
my ($module, $value, $symbol, $gpl) = @{$SYMBOL{$sym}};
$SYMBOL{ $sym } = [ $module, $value+1, $symbol, $gpl];
push(@{$MODULE{$thismod}} , $sym);
}
}
- if ($state != 3) {
+ if ($state != 2) {
warn "WARNING:$thismod is not built with CONFIG_MODVERSIONS enabled\n";
$modversion_warnings++;
}
--
2.47.0.rc1.288.g06298d1525-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v6 4/5] modpost: Produce extended MODVERSIONS information
2024-10-15 23:18 ` [PATCH v6 4/5] modpost: Produce extended MODVERSIONS information Matthew Maurer
@ 2024-10-17 0:25 ` Sami Tolvanen
2024-10-21 18:48 ` Luis Chamberlain
2024-10-21 18:50 ` Luis Chamberlain
2 siblings, 0 replies; 13+ messages in thread
From: Sami Tolvanen @ 2024-10-17 0:25 UTC (permalink / raw)
To: Matthew Maurer
Cc: masahiroy, ndesaulniers, ojeda, gary, mcgrof, Alex Gaynor,
rust-for-linux, linux-kbuild, linux-kernel, neal, marcan, j,
asahi, linux-modules, Petr Pavlu, Daniel Gomez, Nathan Chancellor,
Nicolas Schier, Boqun Feng, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross
Hi Matt,
On Tue, Oct 15, 2024 at 4:19 PM Matthew Maurer <mmaurer@google.com> wrote:
>
> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index 107393a8c48a..d18ff8a1109a 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -1840,15 +1840,56 @@ static void add_versions(struct buffer *b, struct module *mod)
> continue;
> }
> if (strlen(s->name) >= MODULE_NAME_LEN) {
> +#ifdef CONFIG_EXTENDED_MODVERSIONS
> + /* this symbol will only be in the extended info */
> + continue;
> +#else
> error("too long symbol \"%s\" [%s.ko]\n",
> s->name, mod->name);
> break;
> +#endif
I applied these patches to my test tree[1] and have the following
options enabled in my .config:
$ grep -E 'MODVERSIONS|GEN.*KSYMS' .config
CONFIG_HAVE_ASM_MODVERSIONS=y
CONFIG_MODVERSIONS=y
# CONFIG_GENKSYMS is not set
CONFIG_GENDWARFKSYMS=y
CONFIG_ASM_MODVERSIONS=y
CONFIG_EXTENDED_MODVERSIONS=y
When I try to build a Rust module, I still get the following error:
ERROR: modpost: too long symbol
"_RNvXs2_NtNtNtCsivAAjSnxUpM_4core3fmt3num3implNtB9_7Display3fmt"
[samples/rust/rust_print.ko]
I suspect gating this behind a config would require you to add a new
command line flag to modpost and check for CONFIG_EXTENDED_MODVERSIONS
in scripts/Makefile.modpost instead.
[1] https://github.com/samitolvanen/linux/commits/rustmodversions
Sami
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 1/5] export_report: Rehabilitate script
2024-10-15 23:18 ` [PATCH v6 1/5] export_report: Rehabilitate script Matthew Maurer
@ 2024-10-17 0:29 ` Sami Tolvanen
2024-10-21 18:42 ` Luis Chamberlain
2024-10-28 13:13 ` Masahiro Yamada
1 sibling, 1 reply; 13+ messages in thread
From: Sami Tolvanen @ 2024-10-17 0:29 UTC (permalink / raw)
To: Matthew Maurer
Cc: masahiroy, ndesaulniers, ojeda, gary, mcgrof, Alex Gaynor,
rust-for-linux, linux-kbuild, linux-kernel, neal, marcan, j,
asahi, linux-modules, Boqun Feng, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross
Hi,
On Tue, Oct 15, 2024 at 4:19 PM Matthew Maurer <mmaurer@google.com> wrote:
>
> The `export_report.pl` script was broken [1] a while back due to a code
> cleanup causing the regex to no longer match. Additionally, it assumes a
> `modules.order` file containing `.ko` in a build directory with `.mod.c`
> files. I cannot find when this would have been the case in the history,
> as normally `.ko` files only appear in `modules.order` in installed
> modules directories, and those do not contain `.mod.c` files.
> This patch makes it able to report symbol usage counts for a build tree
> with modules and MODVERSIONS.
>
> Since the rest of this series will change the format of `.mod.c`, this
> change fixes the script to work correctly against a current build tree.
> Given that the regex no longer matches the format used in `.mod.c`, it
> cannot have worked since 2019, so updating this script is purely out of
> an abundance of caution. I am unsure who uses this script or for what
> purpose.
>
> * modules.order in a build directory uses .o, not .ko files. Allow .o
> files when parsing modules.order.
> * The .mod.c format changed [1] how it expressed the section attribute,
> leading to a regex mismatch. Update it to match modpost.c
>
> [1]: https://lore.kernel.org/all/20190909113423.2289-2-yamada.masahiro@socionext.com/
If this script has been broken for half a decade and nobody noticed,
does anyone actually use it? If this is dead code, I would prefer to
just delete it.
Sami
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 1/5] export_report: Rehabilitate script
2024-10-17 0:29 ` Sami Tolvanen
@ 2024-10-21 18:42 ` Luis Chamberlain
0 siblings, 0 replies; 13+ messages in thread
From: Luis Chamberlain @ 2024-10-21 18:42 UTC (permalink / raw)
To: Sami Tolvanen
Cc: Matthew Maurer, masahiroy, ndesaulniers, ojeda, gary, Alex Gaynor,
rust-for-linux, linux-kbuild, linux-kernel, neal, marcan, j,
asahi, linux-modules, Boqun Feng, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross
On Wed, Oct 16, 2024 at 05:29:21PM -0700, Sami Tolvanen wrote:
> Hi,
>
> On Tue, Oct 15, 2024 at 4:19 PM Matthew Maurer <mmaurer@google.com> wrote:
> >
> > The `export_report.pl` script was broken [1] a while back due to a code
> > cleanup causing the regex to no longer match. Additionally, it assumes a
> > `modules.order` file containing `.ko` in a build directory with `.mod.c`
> > files. I cannot find when this would have been the case in the history,
> > as normally `.ko` files only appear in `modules.order` in installed
> > modules directories, and those do not contain `.mod.c` files.
> > This patch makes it able to report symbol usage counts for a build tree
> > with modules and MODVERSIONS.
> >
> > Since the rest of this series will change the format of `.mod.c`, this
> > change fixes the script to work correctly against a current build tree.
> > Given that the regex no longer matches the format used in `.mod.c`, it
> > cannot have worked since 2019, so updating this script is purely out of
> > an abundance of caution. I am unsure who uses this script or for what
> > purpose.
> >
> > * modules.order in a build directory uses .o, not .ko files. Allow .o
> > files when parsing modules.order.
> > * The .mod.c format changed [1] how it expressed the section attribute,
> > leading to a regex mismatch. Update it to match modpost.c
> >
> > [1]: https://lore.kernel.org/all/20190909113423.2289-2-yamada.masahiro@socionext.com/
>
> If this script has been broken for half a decade and nobody noticed,
> does anyone actually use it? If this is dead code, I would prefer to
> just delete it.
I'm in full agreement, please trace back the history down to why the
heck we have this, otherwise chuck it.
Luis
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 2/5] modules: Support extended MODVERSIONS info
2024-10-15 23:18 ` [PATCH v6 2/5] modules: Support extended MODVERSIONS info Matthew Maurer
@ 2024-10-21 18:44 ` Luis Chamberlain
0 siblings, 0 replies; 13+ messages in thread
From: Luis Chamberlain @ 2024-10-21 18:44 UTC (permalink / raw)
To: Matthew Maurer, linuxppc-dev
Cc: masahiroy, ndesaulniers, ojeda, gary, Michael Ellerman,
Alex Gaynor, Naveen N Rao, Arnd Bergmann,
Mike Rapoport (Microsoft), Benjamin Gray, rust-for-linux,
linux-kbuild, linux-kernel, neal, marcan, j, asahi, linux-modules,
samitolvanen, Nicholas Piggin, Christophe Leroy,
Madhavan Srinivasan, Petr Pavlu, Daniel Gomez, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Andrew Morton
On Tue, Oct 15, 2024 at 11:18:57PM +0000, Matthew Maurer wrote:
> Adds a new format for MODVERSIONS which stores each field in a separate
> ELF section. This initially adds support for variable length names, but
> could later be used to add additional fields to MODVERSIONS in a
> backwards compatible way if needed. Any new fields will be ignored by
> old user tooling, unlike the current format where user tooling cannot
> tolerate adjustments to the format (for example making the name field
> longer).
>
> Since PPC munges its version records to strip leading dots, we reproduce
> the munging for the new format. Other architectures do not appear to
> have architecture-specific usage of this information.
I'd like some PPC person to review this, and also please document
this under dedotify_ext_version_names().
Luis
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 4/5] modpost: Produce extended MODVERSIONS information
2024-10-15 23:18 ` [PATCH v6 4/5] modpost: Produce extended MODVERSIONS information Matthew Maurer
2024-10-17 0:25 ` Sami Tolvanen
@ 2024-10-21 18:48 ` Luis Chamberlain
2024-10-21 18:50 ` Luis Chamberlain
2 siblings, 0 replies; 13+ messages in thread
From: Luis Chamberlain @ 2024-10-21 18:48 UTC (permalink / raw)
To: Matthew Maurer
Cc: masahiroy, ndesaulniers, ojeda, gary, Alex Gaynor, rust-for-linux,
linux-kbuild, linux-kernel, neal, marcan, j, asahi, linux-modules,
samitolvanen, Petr Pavlu, Daniel Gomez, Nathan Chancellor,
Nicolas Schier, Boqun Feng, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross
On Tue, Oct 15, 2024 at 11:18:59PM +0000, Matthew Maurer wrote:
> Generate both the existing modversions format and the new extended one
> when running modpost. Presence of this metadata in the final .ko is
> guarded by CONFIG_EXTENDED_MODVERSIONS.
>
> We no longer generate an error on long symbols in modpost if
> CONFIG_EXTENDED_MODVERSIONS is set, as they can now be appropriately
> encoded in the extended section. These symbols will be skipped in the
> previous encoding. An error will still be generated if
> CONFIG_EXTENDED_MODVERSIONS is not set.
>
> Signed-off-by: Matthew Maurer <mmaurer@google.com>
> ---
> kernel/module/Kconfig | 8 ++++++++
> scripts/mod/modpost.c | 41 +++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 49 insertions(+)
>
> diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig
> index 7c6588148d42..a5de2b7f2758 100644
> --- a/kernel/module/Kconfig
> +++ b/kernel/module/Kconfig
> @@ -177,6 +177,14 @@ config ASM_MODVERSIONS
> assembly. This can be enabled only when the target architecture
> supports it.
>
> +config EXTENDED_MODVERSIONS
> + bool "Extended Module Versioning Support"
> + depends on MODVERSIONS
> + help
> + This enables extended MODVERSIONs support, allowing long symbol
> + names to be versioned. The most likely reasons you would enable
> + this are for Rust usage or aggressive LTO configurations.
What is "aggressive LTO configurations" please elaborate. Can we infer
on that through configuration?
> +
> config MODULE_SRCVERSION_ALL
> bool "Source checksum for all modules"
> help
> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index 107393a8c48a..d18ff8a1109a 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -1840,15 +1840,56 @@ static void add_versions(struct buffer *b, struct module *mod)
> continue;
> }
> if (strlen(s->name) >= MODULE_NAME_LEN) {
> +#ifdef CONFIG_EXTENDED_MODVERSIONS
> + /* this symbol will only be in the extended info */
> + continue;
> +#else
> error("too long symbol \"%s\" [%s.ko]\n",
> s->name, mod->name);
> break;
> +#endif
> }
Using #ifdefs on a loop like this seems fragile, even if its more code
make the code clearer and use separate routines for both worlds. Make
the code easy to review and maintain.
> buf_printf(b, "\t{ %#8x, \"%s\" },\n",
> s->crc, s->name);
> }
>
> buf_printf(b, "};\n");
> +
> + buf_printf(b, "#ifdef CONFIG_EXTENDED_MODVERSIONS\n");
Why not *in-code* rather than the output? And if possible why not
two routines as above.
Luis
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 4/5] modpost: Produce extended MODVERSIONS information
2024-10-15 23:18 ` [PATCH v6 4/5] modpost: Produce extended MODVERSIONS information Matthew Maurer
2024-10-17 0:25 ` Sami Tolvanen
2024-10-21 18:48 ` Luis Chamberlain
@ 2024-10-21 18:50 ` Luis Chamberlain
2 siblings, 0 replies; 13+ messages in thread
From: Luis Chamberlain @ 2024-10-21 18:50 UTC (permalink / raw)
To: Matthew Maurer
Cc: masahiroy, ndesaulniers, ojeda, gary, Alex Gaynor, rust-for-linux,
linux-kbuild, linux-kernel, neal, marcan, j, asahi, linux-modules,
samitolvanen, Petr Pavlu, Daniel Gomez, Nathan Chancellor,
Nicolas Schier, Boqun Feng, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross
On Tue, Oct 15, 2024 at 11:18:59PM +0000, Matthew Maurer wrote:
> Generate both the existing modversions format and the new extended one
> when running modpost. Presence of this metadata in the final .ko is
> guarded by CONFIG_EXTENDED_MODVERSIONS.
>
> We no longer generate an error on long symbols in modpost if
> CONFIG_EXTENDED_MODVERSIONS is set, as they can now be appropriately
> encoded in the extended section. These symbols will be skipped in the
> previous encoding. An error will still be generated if
> CONFIG_EXTENDED_MODVERSIONS is not set.
>
> Signed-off-by: Matthew Maurer <mmaurer@google.com>
If nothing is selecting EXTENDED_MODVERSIONS then this is dead code and
should not be submitted unless we have a user, if that's the case then
this series should be folded into Sami's.
Luis
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v6 1/5] export_report: Rehabilitate script
2024-10-15 23:18 ` [PATCH v6 1/5] export_report: Rehabilitate script Matthew Maurer
2024-10-17 0:29 ` Sami Tolvanen
@ 2024-10-28 13:13 ` Masahiro Yamada
1 sibling, 0 replies; 13+ messages in thread
From: Masahiro Yamada @ 2024-10-28 13:13 UTC (permalink / raw)
To: Matthew Maurer
Cc: ndesaulniers, ojeda, gary, mcgrof, Alex Gaynor, rust-for-linux,
linux-kbuild, linux-kernel, neal, marcan, j, asahi, linux-modules,
samitolvanen, Boqun Feng, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross
On Wed, Oct 16, 2024 at 1:19 AM Matthew Maurer <mmaurer@google.com> wrote:
>
> The `export_report.pl` script was broken [1] a while back due to a code
> cleanup causing the regex to no longer match.
Instead of the link to lore, you can refer to
commit a3d0cb04f7df ("modpost: use __section in the output to *.mod.c")
> Additionally, it assumes a
> `modules.order` file containing `.ko` in a build directory with `.mod.c`
> files. I cannot find when this would have been the case in the history,
> as normally `.ko` files only appear in `modules.order` in installed
> modules directories, and those do not contain `.mod.c` files.
If necessary, you can refer to
commit f65a486821cf ("kbuild: change module.order to list *.o instead of *.ko")
As suggested, I vote for the removal since it has been broken for 5 years
since a3d0cb04f7df.
--
Best Regards
Masahiro Yamada
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2024-10-28 13:14 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-15 23:18 [PATCH v6 0/5] Extended MODVERSIONS Support Matthew Maurer
2024-10-15 23:18 ` [PATCH v6 1/5] export_report: Rehabilitate script Matthew Maurer
2024-10-17 0:29 ` Sami Tolvanen
2024-10-21 18:42 ` Luis Chamberlain
2024-10-28 13:13 ` Masahiro Yamada
2024-10-15 23:18 ` [PATCH v6 2/5] modules: Support extended MODVERSIONS info Matthew Maurer
2024-10-21 18:44 ` Luis Chamberlain
2024-10-15 23:18 ` [PATCH v6 3/5] export_report: Tolerate additional `.mod.c` content Matthew Maurer
2024-10-15 23:18 ` [PATCH v6 4/5] modpost: Produce extended MODVERSIONS information Matthew Maurer
2024-10-17 0:25 ` Sami Tolvanen
2024-10-21 18:48 ` Luis Chamberlain
2024-10-21 18:50 ` Luis Chamberlain
2024-10-15 23:19 ` [PATCH v6 5/5] export_report: Use new version info format Matthew Maurer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).