From c46191028edc02c70a1023d5d38cffe5133a65ad Mon Sep 17 00:00:00 2001 From: Artem Savkov Date: Wed, 17 Oct 2018 10:15:16 +0200 Subject: [PATCH 1/2] strdup symbol names from kelf_base strdup symbol names in kpatch_elf_locals and when noting down hint instead of just copying pointers so that they are still usable after we teardown/free kelf_base. Signed-off-by: Artem Savkov --- kpatch-build/create-diff-object.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index a24927f..cd138be 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -2482,7 +2482,7 @@ static struct sym_compare_type *kpatch_elf_locals(struct kpatch_elf *kelf) continue; sym_array[i].type = sym->type; - sym_array[i++].name = sym->name; + sym_array[i++].name = strdup(sym->name); } sym_array[i].type = 0; sym_array[i].name = NULL; @@ -3229,7 +3229,7 @@ int main(int argc, char *argv[]) struct symbol *sym; char *hint = NULL, *orig_obj, *patched_obj, *parent_name; char *parent_symtab, *mod_symvers, *patch_name, *output_obj; - struct sym_compare_type *base_locals; + struct sym_compare_type *base_locals, *sym_comp; arguments.debug = 0; argp_parse (&argp, argc, argv, 0, NULL, &arguments); @@ -3263,7 +3263,7 @@ int main(int argc, char *argv[]) list_for_each_entry(sym, &kelf_base->symbols, list) { if (sym->type == STT_FILE) { - hint = sym->name; + hint = strdup(sym->name); break; } } @@ -3275,7 +3275,11 @@ int main(int argc, char *argv[]) /* create symbol lookup table */ base_locals = kpatch_elf_locals(kelf_base); lookup = lookup_open(parent_symtab, mod_symvers, hint, base_locals); + for (sym_comp = base_locals; sym_comp->name; sym_comp++) { + free(sym_comp->name); + } free(base_locals); + free(hint); kpatch_mark_grouped_sections(kelf_patched); kpatch_replace_sections_syms(kelf_base); From f959edecdb13f940e48353c02cabc8f2dbb528fb Mon Sep 17 00:00:00 2001 From: Artem Savkov Date: Tue, 16 Oct 2018 10:48:31 +0200 Subject: [PATCH 2/2] Move lookup_open() call to a later stage Sometimes due to config-dependency issues or other reasons whole object-files would get optimized out from final vmlinux/module, in cases like this create-diff-object would fail during symbol lookup table creation in lookup_open(). Because lookup_open() call is situated before we established that objectfile has changed this triggers not only on real problems, but also during mass-rebulds caused by changes to header-files. While it usually indicates a real issue with config this should not prevent kpatch from building. Move lookup_open() call so that it is called only for changed object-files. Fixes #910 Signed-off-by: Artem Savkov --- kpatch-build/create-diff-object.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index cd138be..0cd4ea8 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -3272,14 +3272,7 @@ int main(int argc, char *argv[]) return EXIT_STATUS_NO_CHANGE; } - /* create symbol lookup table */ base_locals = kpatch_elf_locals(kelf_base); - lookup = lookup_open(parent_symtab, mod_symvers, hint, base_locals); - for (sym_comp = base_locals; sym_comp->name; sym_comp++) { - free(sym_comp->name); - } - free(base_locals); - free(hint); kpatch_mark_grouped_sections(kelf_patched); kpatch_replace_sections_syms(kelf_base); @@ -3336,6 +3329,14 @@ int main(int argc, char *argv[]) */ kpatch_elf_teardown(kelf_patched); + /* create symbol lookup table */ + lookup = lookup_open(parent_symtab, mod_symvers, hint, base_locals); + for (sym_comp = base_locals; sym_comp->name; sym_comp++) { + free(sym_comp->name); + } + free(base_locals); + free(hint); + /* create strings, patches, and dynrelas sections */ kpatch_create_strings_elements(kelf_out); kpatch_create_patches_sections(kelf_out, lookup, parent_name);