create-diff-object: Don't strip callback section symbols

Internal CI is reporting a SIGSEGV in create-diff-object when it
processes macro-callbacks.patch, starting with 19baa5b7c7
("create-diff-object: process debug sections last").

The problem is that, after changing the order between callback and debug
section inclusion, kpatch_include_debug_sections() now tries to include
the callback section symbols.  But kpatch_include_callback_elements()
inadvertently un-includes the callback section symbols (e.g.,
".kpatch.callbacks.pre_patch") when it un-includes the callback struct
symbols (e.g., "kpatch_pre_patch_data").

So after kpatch_elf_teardown(kelf_patched), the callback section symbols
get freed even though there are DWARF .debug_info relocations which
reference them.  Then kpatch_check_relocations() goes off into the weeds
when it accesses one of the freed symbols.

Fix it by refining the callback un-include logic so that it *only*
strips the struct object symbols.

Fixes: 19baa5b7c7 ("create-diff-object: process debug sections last")
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
This commit is contained in:
Josh Poimboeuf 2020-02-18 10:16:39 -06:00
parent 648be4c380
commit 687e2caabc
1 changed files with 3 additions and 2 deletions

View File

@ -1570,9 +1570,10 @@ static int kpatch_include_callback_elements(struct kpatch_elf *kelf)
}
}
/* Strip temporary global structures used by the callback macros. */
/* Strip temporary structure symbols used by the callback macros. */
list_for_each_entry(sym, &kelf->symbols, list) {
if (sym->sec && is_callback_section(sym->sec))
if (sym->type == STT_OBJECT && sym->sec &&
is_callback_section(sym->sec))
sym->include = 0;
}