Skip to content

Commit ab10815

Browse files
petrpavlujpoimboe
authored andcommitted
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: dd590d4 ("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>
1 parent a8ff29f commit ab10815

4 files changed

Lines changed: 32 additions & 17 deletions

File tree

include/linux/livepatch.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ int klp_enable_patch(struct klp_patch *);
175175
int klp_module_coming(struct module *mod);
176176
void klp_module_going(struct module *mod);
177177

178+
void *klp_find_section_by_name(const struct module *mod, const char *name,
179+
size_t *sec_size);
180+
178181
void klp_copy_process(struct task_struct *child);
179182
void klp_update_patch_state(struct task_struct *task);
180183

kernel/livepatch/core.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,6 +1356,25 @@ void klp_module_going(struct module *mod)
13561356
mutex_unlock(&klp_mutex);
13571357
}
13581358

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+
13591378
static int __init klp_init(void)
13601379
{
13611380
klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj);

scripts/livepatch/init.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@
99
#include <linux/slab.h>
1010
#include <linux/livepatch.h>
1111

12-
extern struct klp_object_ext __start_klp_objects[];
13-
extern struct klp_object_ext __stop_klp_objects[];
14-
1512
static struct klp_patch *patch;
1613

1714
static int __init livepatch_mod_init(void)
1815
{
16+
struct klp_object_ext *obj_exts;
17+
size_t obj_exts_sec_size;
1918
struct klp_object *objs;
2019
unsigned int nr_objs;
2120
int ret;
2221

23-
nr_objs = __stop_klp_objects - __start_klp_objects;
24-
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);
2525
if (!nr_objs) {
2626
pr_err("nothing to patch!\n");
2727
ret = -EINVAL;
@@ -41,7 +41,7 @@ static int __init livepatch_mod_init(void)
4141
}
4242

4343
for (int i = 0; i < nr_objs; i++) {
44-
struct klp_object_ext *obj_ext = __start_klp_objects + i;
44+
struct klp_object_ext *obj_ext = obj_exts + i;
4545
struct klp_func_ext *funcs_ext = obj_ext->funcs;
4646
unsigned int nr_funcs = obj_ext->nr_funcs;
4747
struct klp_func *funcs = objs[i].funcs;
@@ -90,12 +90,10 @@ static int __init livepatch_mod_init(void)
9090

9191
static void __exit livepatch_mod_exit(void)
9292
{
93-
unsigned int nr_objs;
94-
95-
nr_objs = __stop_klp_objects - __start_klp_objects;
93+
struct klp_object *obj;
9694

97-
for (int i = 0; i < nr_objs; i++)
98-
kfree(patch->objs[i].funcs);
95+
klp_for_each_object_static(patch, obj)
96+
kfree(obj->funcs);
9997

10098
kfree(patch->objs);
10199
kfree(patch);

scripts/module.lds.S

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,7 @@ SECTIONS {
3535
__patchable_function_entries : { *(__patchable_function_entries) }
3636

3737
__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-
}
38+
__klp_objects 0: ALIGN(8) { KEEP(*(__klp_objects)) }
4439

4540
#ifdef CONFIG_ARCH_USES_CFI_TRAPS
4641
__kcfi_traps : { KEEP(*(.kcfi_traps)) }

0 commit comments

Comments
 (0)