create-diff-object: include .LCx string literal symbols

A seg fault was reported:

  Program received signal SIGSEGV, Segmentation fault.
  0x00007ffff7f18c8e in __strcmp_avx2 () from /lib64/libc.so.6
  Missing separate debuginfos, use: dnf debuginfo-install elfutils-libelf-0.186-1.fc34.x86_64 zlib-1.2.11-26.fc34.x86_64
  (gdb) bt
  #0  0x00007ffff7f18c8e in __strcmp_avx2 () from /lib64/libc.so.6
  #1  0x000000000040a0f7 in kpatch_is_core_module_symbol (name=0x0) at create-diff-object.c:3060
  #2  0x000000000040a267 in need_dynrela (kelf=0x4669a0, table=0x92af30, sec=0x6d6b20, rela=0x8c7fd0) at create-diff-object.c:3117
  #3  0x000000000040a4cc in kpatch_create_intermediate_sections (kelf=0x4669a0, table=0x92af30, objname=0x7fffffffcfc6 "vmlinux", pmod_name=0x7fffffffd020 "livepatch_a") at create-diff-object.c:3281
  #4  0x000000000040c7c5 in main (argc=8, argv=0x7fffffffca48) at create-diff-object.c:3931

It happened because 'rela->sym->name' was NULL, and
kpatch_is_core_module_symbol() tried to dereference it.

Here's the corresponding relocation:

  Relocation section [455] '.rela.debug_loclists' for section [454] '.debug_loclists' at offset 0xd0478 contains 2432 entries:
    Offset              Type            Value               Addend Name
    ...
    0x000000000000aad6  X86_64_64       000000000000000000     +32 .LC55
    ...

That '.LC55' symbol lives in the following section:

  [104] .rodata.btf_show_end_aggr_type.str1.8 PROGBITS     0000000000000000 00003ef0 00000021  1 AMS    0   0  8

The problem is that the symbol wasn't included in the output file
(though its corresponding section was).  So it got zeroed by
kpatch_elf_teardown(), which was designed to trigger seg faults to help
find bugs like this.

The string literal sections which hold the '.LCx' string symbols are
already being included.  Include their symbols as well.

Fixes #1257.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
This commit is contained in:
Josh Poimboeuf 2022-04-06 12:53:04 -07:00
parent 75f220233b
commit 305ff8a5d8
1 changed files with 15 additions and 14 deletions

View File

@ -1021,18 +1021,9 @@ static void kpatch_correlate_symbols(struct list_head *symlist_orig,
continue;
/*
* The .LCx symbols point to strings, usually used for
* the bug table. Don't correlate and compare the
* symbols themselves, because the suffix number might
* change.
*
* If the symbol is used by the bug table (usual case),
* it may get pulled in by
* kpatch_regenerate_special_section().
*
* If the symbol is used outside of the bug table (not
* sure if this actually happens anywhere), any string
* changes will be detected elsewhere in rela_equal().
* The .LCx symbols point to string literals in
* '.rodata.<func>.str1.*' sections. They get included
* in kpatch_include_standard_elements().
*/
if (sym_orig->type == STT_NOTYPE &&
!strncmp(sym_orig->name, ".LC", 3))
@ -1748,9 +1739,16 @@ static void kpatch_include_symbol(struct symbol *sym)
kpatch_include_section(sym->sec);
}
static bool is_string_literal_section(struct section *sec)
{
return !strncmp(sec->name, ".rodata.", 8) &&
strstr(sec->name, ".str1.");
}
static void kpatch_include_standard_elements(struct kpatch_elf *kelf)
{
struct section *sec;
struct symbol *sym;
list_for_each_entry(sec, &kelf->sections, list) {
/*
@ -1780,12 +1778,15 @@ static void kpatch_include_standard_elements(struct kpatch_elf *kelf)
!strcmp(sec->name, ".symtab") ||
!strcmp(sec->name, ".toc") ||
!strcmp(sec->name, ".rodata") ||
(!strncmp(sec->name, ".rodata.", 8) &&
strstr(sec->name, ".str1."))) {
is_string_literal_section(sec)) {
kpatch_include_section(sec);
}
}
list_for_each_entry(sym, &kelf->symbols, list)
if (sym->sec && is_string_literal_section(sym->sec))
sym->include = 1;
/* include the NULL symbol */
list_entry(kelf->symbols.next, struct symbol, list)->include = 1;
}