From 7dfad2fb7603aa770b37e1ac424ad93cb0abab19 Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Wed, 13 Aug 2014 13:32:08 -0500 Subject: [PATCH] fix dynrela corruption in load/unload hooks In kpatch_create_dynamic_rela_sections() the dest field is filled in with either the function symbol or the section symbol that contains the function depending on whether or not the sym field of the base section is NULL or not (around line 2153). In the case of the hook functions, we strip the FUNC symbol to prevent it from being added to the kpatch.funcs section as a patched function. However we weren't unbundling the stripped symbol from the section. This resulted in the sym field pointing to the null symbol (index 0), corrupting the dynrelas rela section. Before: Relocation section [14] '.rela.kpatch.dynrelas' for section [13] '.kpatch.dynrelas' at offset 0x8b8 contains 6 entries: Offset Type Value Addend Name 000000000000000000 X86_64_64 000000000000000000 +9 0x0000000000000018 X86_64_64 000000000000000000 +8 .kpatch.strings 0x0000000000000020 X86_64_64 000000000000000000 +0 .kpatch.strings 0x0000000000000030 X86_64_64 000000000000000000 +9 0x0000000000000048 X86_64_64 000000000000000000 +8 .kpatch.strings 0x0000000000000050 X86_64_64 000000000000000000 +0 .kpatch.strings This commit unbundles the stripped symbol from the section so that the section symbol is used in the dynrelas rela section. After: Relocation section [14] '.rela.kpatch.dynrelas' for section [13] '.kpatch.dynrelas' at offset 0x8b8 contains 6 entries: Offset Type Value Addend Name 000000000000000000 X86_64_64 000000000000000000 +9 .text.kpatch_load_aio_max_nr 0x0000000000000018 X86_64_64 000000000000000000 +8 .kpatch.strings 0x0000000000000020 X86_64_64 000000000000000000 +0 .kpatch.strings 0x0000000000000030 X86_64_64 000000000000000000 +9 .text.kpatch_unload_aio_max_nr 0x0000000000000048 X86_64_64 000000000000000000 +8 .kpatch.strings 0x0000000000000050 X86_64_64 000000000000000000 +0 .kpatch.strings Signed-off-by: Seth Jennings --- kpatch-build/create-diff-object.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index e29ba3b..8bf2327 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -1212,6 +1212,7 @@ int kpatch_include_hook_elements(struct kpatch_elf *kelf) kpatch_include_symbol(sym, 0); /* strip the hook symbol */ sym->include = 0; + sym->sec->sym = NULL; /* use section symbol instead */ rela->sym = sym->sec->secsym; } else {