On Mon, Jun 09, 2025 at 10:05:53PM -0400, Joe Lawrence wrote: > On Mon, Jun 09, 2025 at 04:59:37PM -0700, Josh Poimboeuf wrote: > > On Mon, Jun 09, 2025 at 05:20:53PM -0400, Joe Lawrence wrote: > > > If you touch sound/soc/sof/intel/, klp-build will error out with: > > > > > > Building patch module: livepatch-unCVE-2024-58012.ko > > > ERROR: modpost: module livepatch-unCVE-2024-58012 uses symbol > > > hda_dai_config from namespace SND_SOC_SOF_INTEL_HDA_COMMON, but does not > > > import it. > > > ERROR: modpost: module livepatch-unCVE-2024-58012 uses symbol > > > hdac_bus_eml_sdw_map_stream_ch from namespace SND_SOC_SOF_HDA_MLINK, but > > > does not import it. > > > make[2]: *** [scripts/Makefile.modpost:145: > > > /home/jolawren/src/centos-stream-10/klp-tmp/kmod/Module.symvers] Error 1 > > > make[1]: *** [/home/jolawren/src/centos-stream-10/Makefile:1936: > > > modpost] Error 2 > > > make: *** [Makefile:236: __sub-make] Error 2 > > > > > > since the diff objects do not necessarily carry forward the namespace > > > import. > > > > Nice, thanks for finding that. I completely forgot about export > > namespaces. > > > > Can you send me the patch for testing? Is this the default centos10 > > config? > > > > Yeah, cs-10 sets CONFIG_NAMESPACES=y. > > The hack I posted earlier abused modinfo to get the namespaces. You > could just dump the import_ns= strings in the .modinfo section with > readelf like (lightly tested):
Sorry, I wasn't clear, I meant the original .patch for recreating the issue. But that's ok, I think the below fix should work. This is basically the same approach as yours, but in klp-diff. It copies from the patched object instead of the orig object in case the patch needs to add an IMPORT_NS(). I also experimented with reading the namespaces from Module.symvers, and then adding them on demand for exported symbols in clone_symbol(). But this is simpler. diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index a1c72824f442..3139f1ebacce 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -1490,6 +1490,51 @@ static int create_klp_sections(struct elfs *e) return 0; } +/* + * Copy all .modinfo import_ns= tags to ensure all namespaced exported symbols + * can be accessed via normal relocs. + */ +static int copy_import_ns(struct elfs *e) +{ + struct section *patched_sec, *out_sec = NULL; + char *import_ns, *data_end; + + patched_sec = find_section_by_name(e->patched, ".modinfo"); + if (!patched_sec) + return 0; + + import_ns = patched_sec->data->d_buf; + if (!import_ns) + return 0; + + for (data_end = import_ns + sec_size(patched_sec); + import_ns < data_end; + import_ns += strlen(import_ns) + 1) { + + import_ns = memmem(import_ns, data_end - import_ns, "import_ns=", 10); + if (!import_ns) + return 0; + + if (!out_sec) { + out_sec = find_section_by_name(e->out, ".modinfo"); + if (!out_sec) { + out_sec = elf_create_section(e->out, ".modinfo", 0, + patched_sec->sh.sh_entsize, + patched_sec->sh.sh_type, + patched_sec->sh.sh_addralign, + patched_sec->sh.sh_flags); + if (!out_sec) + return -1; + } + } + + if (!elf_add_data(e->out, out_sec, import_ns, strlen(import_ns) + 1)) + return -1; + } + + return 0; +} + int cmd_klp_diff(int argc, const char **argv) { struct elfs e = {0}; @@ -1539,6 +1584,9 @@ int cmd_klp_diff(int argc, const char **argv) if (create_klp_sections(&e)) return -1; + if (copy_import_ns(&e)) + return -1; + if (elf_write(e.out)) return -1;