livepatch: Fix having __klp_objects relics in non-livepatch modules

The linker script scripts/module.lds.S specifies that all input
__klp_objects sections should be consolidated into an output section of
the same name, and start/stop symbols should be created to enable
scripts/livepatch/init.c to locate this data.

This start/stop pattern is not ideal for modules because the symbols are
created even if no __klp_objects input sections are present.
Consequently, a dummy __klp_objects section also appears in the
resulting module. This unnecessarily pollutes non-livepatch modules.

Instead, since modules are relocatable files, the usual method for
locating consolidated data in a module is to read its section table.
This approach avoids the aforementioned problem.

The klp_modinfo already stores a copy of the entire section table with
the final addresses. Introduce a helper function that
scripts/livepatch/init.c can call to obtain the location of the
__klp_objects section from this data.

Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Acked-by: Miroslav Benes <mbenes@suse.cz>
Reviewed-by: Aaron Tomlin <atomlin@atomlin.com>
Link: https://patch.msgid.link/20260123102825.3521961-2-petr.pavlu@suse.com
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>

authored by Petr Pavlu and committed by Josh Poimboeuf ab108154 a8ff29f0

+32 -17
+3
include/linux/livepatch.h
··· 175 int klp_module_coming(struct module *mod); 176 void klp_module_going(struct module *mod); 177 178 void klp_copy_process(struct task_struct *child); 179 void klp_update_patch_state(struct task_struct *task); 180
··· 175 int klp_module_coming(struct module *mod); 176 void klp_module_going(struct module *mod); 177 178 + void *klp_find_section_by_name(const struct module *mod, const char *name, 179 + size_t *sec_size); 180 + 181 void klp_copy_process(struct task_struct *child); 182 void klp_update_patch_state(struct task_struct *task); 183
+19
kernel/livepatch/core.c
··· 1356 mutex_unlock(&klp_mutex); 1357 } 1358 1359 static int __init klp_init(void) 1360 { 1361 klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj);
··· 1356 mutex_unlock(&klp_mutex); 1357 } 1358 1359 + void *klp_find_section_by_name(const struct module *mod, const char *name, 1360 + size_t *sec_size) 1361 + { 1362 + struct klp_modinfo *info = mod->klp_info; 1363 + 1364 + for (int i = 1; i < info->hdr.e_shnum; i++) { 1365 + Elf_Shdr *shdr = &info->sechdrs[i]; 1366 + 1367 + if (!strcmp(info->secstrings + shdr->sh_name, name)) { 1368 + *sec_size = shdr->sh_size; 1369 + return (void *)shdr->sh_addr; 1370 + } 1371 + } 1372 + 1373 + *sec_size = 0; 1374 + return NULL; 1375 + } 1376 + EXPORT_SYMBOL_GPL(klp_find_section_by_name); 1377 + 1378 static int __init klp_init(void) 1379 { 1380 klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj);
+9 -11
scripts/livepatch/init.c
··· 9 #include <linux/slab.h> 10 #include <linux/livepatch.h> 11 12 - extern struct klp_object_ext __start_klp_objects[]; 13 - extern struct klp_object_ext __stop_klp_objects[]; 14 - 15 static struct klp_patch *patch; 16 17 static int __init livepatch_mod_init(void) 18 { 19 struct klp_object *objs; 20 unsigned int nr_objs; 21 int ret; 22 23 - nr_objs = __stop_klp_objects - __start_klp_objects; 24 - 25 if (!nr_objs) { 26 pr_err("nothing to patch!\n"); 27 ret = -EINVAL; ··· 41 } 42 43 for (int i = 0; i < nr_objs; i++) { 44 - struct klp_object_ext *obj_ext = __start_klp_objects + i; 45 struct klp_func_ext *funcs_ext = obj_ext->funcs; 46 unsigned int nr_funcs = obj_ext->nr_funcs; 47 struct klp_func *funcs = objs[i].funcs; ··· 90 91 static void __exit livepatch_mod_exit(void) 92 { 93 - unsigned int nr_objs; 94 95 - nr_objs = __stop_klp_objects - __start_klp_objects; 96 - 97 - for (int i = 0; i < nr_objs; i++) 98 - kfree(patch->objs[i].funcs); 99 100 kfree(patch->objs); 101 kfree(patch);
··· 9 #include <linux/slab.h> 10 #include <linux/livepatch.h> 11 12 static struct klp_patch *patch; 13 14 static int __init livepatch_mod_init(void) 15 { 16 + struct klp_object_ext *obj_exts; 17 + size_t obj_exts_sec_size; 18 struct klp_object *objs; 19 unsigned int nr_objs; 20 int ret; 21 22 + obj_exts = klp_find_section_by_name(THIS_MODULE, "__klp_objects", 23 + &obj_exts_sec_size); 24 + nr_objs = obj_exts_sec_size / sizeof(*obj_exts); 25 if (!nr_objs) { 26 pr_err("nothing to patch!\n"); 27 ret = -EINVAL; ··· 41 } 42 43 for (int i = 0; i < nr_objs; i++) { 44 + struct klp_object_ext *obj_ext = obj_exts + i; 45 struct klp_func_ext *funcs_ext = obj_ext->funcs; 46 unsigned int nr_funcs = obj_ext->nr_funcs; 47 struct klp_func *funcs = objs[i].funcs; ··· 90 91 static void __exit livepatch_mod_exit(void) 92 { 93 + struct klp_object *obj; 94 95 + klp_for_each_object_static(patch, obj) 96 + kfree(obj->funcs); 97 98 kfree(patch->objs); 99 kfree(patch);
+1 -6
scripts/module.lds.S
··· 35 __patchable_function_entries : { *(__patchable_function_entries) } 36 37 __klp_funcs 0: ALIGN(8) { KEEP(*(__klp_funcs)) } 38 - 39 - __klp_objects 0: ALIGN(8) { 40 - __start_klp_objects = .; 41 - KEEP(*(__klp_objects)) 42 - __stop_klp_objects = .; 43 - } 44 45 #ifdef CONFIG_ARCH_USES_CFI_TRAPS 46 __kcfi_traps : { KEEP(*(.kcfi_traps)) }
··· 35 __patchable_function_entries : { *(__patchable_function_entries) } 36 37 __klp_funcs 0: ALIGN(8) { KEEP(*(__klp_funcs)) } 38 + __klp_objects 0: ALIGN(8) { KEEP(*(__klp_objects)) } 39 40 #ifdef CONFIG_ARCH_USES_CFI_TRAPS 41 __kcfi_traps : { KEEP(*(.kcfi_traps)) }