From 255e732c61dbb6a0bf9e0a3d6bc45f202853c880 Mon Sep 17 00:00:00 2001 From: Jessica Yu Date: Wed, 17 Aug 2016 20:58:28 -0400 Subject: [PATCH 1/4] livepatch: use arch_klp_init_object_loaded() to finish arch-specific tasks Introduce arch_klp_init_object_loaded() to complete any additional arch-specific tasks during patching. Architecture code may override this function. Signed-off-by: Jessica Yu Reviewed-by: Petr Mladek Acked-by: Miroslav Benes Signed-off-by: Jiri Kosina --- include/linux/livepatch.h | 3 +++ kernel/livepatch/core.c | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h index a93a0b23dc8d..9072f04db616 100644 --- a/include/linux/livepatch.h +++ b/include/linux/livepatch.h @@ -116,6 +116,9 @@ int klp_unregister_patch(struct klp_patch *); int klp_enable_patch(struct klp_patch *); int klp_disable_patch(struct klp_patch *); +void arch_klp_init_object_loaded(struct klp_patch *patch, + struct klp_object *obj); + /* Called from the module loader during module coming/going states */ int klp_module_coming(struct module *mod); void klp_module_going(struct module *mod); diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 8bbe50704621..5fbabe022286 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -274,7 +274,6 @@ static int klp_write_object_relocations(struct module *pmod, objname = klp_is_module(obj) ? obj->name : "vmlinux"; - module_disable_ro(pmod); /* For each klp relocation section */ for (i = 1; i < pmod->klp_info->hdr.e_shnum; i++) { sec = pmod->klp_info->sechdrs + i; @@ -309,7 +308,6 @@ static int klp_write_object_relocations(struct module *pmod, break; } - module_enable_ro(pmod, true); return ret; } @@ -763,6 +761,12 @@ static int klp_init_func(struct klp_object *obj, struct klp_func *func) func->old_sympos ? func->old_sympos : 1); } +/* Arches may override this to finish any remaining arch-specific tasks */ +void __weak arch_klp_init_object_loaded(struct klp_patch *patch, + struct klp_object *obj) +{ +} + /* parts of the initialization that is done only when the object is loaded */ static int klp_init_object_loaded(struct klp_patch *patch, struct klp_object *obj) @@ -770,9 +774,15 @@ static int klp_init_object_loaded(struct klp_patch *patch, struct klp_func *func; int ret; + module_disable_ro(patch->mod); ret = klp_write_object_relocations(patch->mod, obj); - if (ret) + if (ret) { + module_enable_ro(patch->mod, true); return ret; + } + + arch_klp_init_object_loaded(patch, obj); + module_enable_ro(patch->mod, true); klp_for_each_func(obj, func) { ret = klp_find_object_symbol(obj->name, func->old_name, From d4c3e6e1b193497da3a2ce495fb1db0243e41e37 Mon Sep 17 00:00:00 2001 From: Jessica Yu Date: Wed, 17 Aug 2016 20:58:29 -0400 Subject: [PATCH 2/4] livepatch/x86: apply alternatives and paravirt patches after relocations Implement arch_klp_init_object_loaded() for x86, which applies alternatives/paravirt patches. This fixes the order in which relocations and alternatives/paravirt patches are applied. Previously, if a patch module had alternatives or paravirt patches, these were applied first by the module loader before livepatch can apply per-object relocations. The (buggy) sequence of events was: (1) Load patch module (2) Apply alternatives and paravirt patches to patch module * Note that these are applied to the new functions in the patch module (3) Apply per-object relocations to patch module when target module loads. * This clobbers what was written in step 2 This lead to crashes and corruption in general, since livepatch would overwrite or step on previously applied alternative/paravirt patches. The correct sequence of events should be: (1) Load patch module (2) Apply per-object relocations to patch module (3) Apply alternatives and paravirt patches to patch module This is fixed by delaying paravirt/alternatives patching until after relocations are applied. Any .altinstructions or .parainstructions sections are prefixed with ".klp.arch.${objname}" and applied in arch_klp_init_object_loaded(). Signed-off-by: Jessica Yu Acked-by: Miroslav Benes Signed-off-by: Jiri Kosina --- arch/x86/kernel/Makefile | 1 + arch/x86/kernel/livepatch.c | 65 +++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 arch/x86/kernel/livepatch.c diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 0503f5bfb18d..4f656fe156fd 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -83,6 +83,7 @@ obj-$(CONFIG_X86_MPPARSE) += mpparse.o obj-y += apic/ obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o +obj-$(CONFIG_LIVEPATCH) += livepatch.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o obj-$(CONFIG_X86_TSC) += trace_clock.o diff --git a/arch/x86/kernel/livepatch.c b/arch/x86/kernel/livepatch.c new file mode 100644 index 000000000000..e9d252d873aa --- /dev/null +++ b/arch/x86/kernel/livepatch.c @@ -0,0 +1,65 @@ +/* + * livepatch.c - x86-specific Kernel Live Patching Core + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include + +/* Apply per-object alternatives. Based on x86 module_finalize() */ +void arch_klp_init_object_loaded(struct klp_patch *patch, + struct klp_object *obj) +{ + int cnt; + struct klp_modinfo *info; + Elf_Shdr *s, *alt = NULL, *para = NULL; + void *aseg, *pseg; + const char *objname; + char sec_objname[MODULE_NAME_LEN]; + char secname[KSYM_NAME_LEN]; + + info = patch->mod->klp_info; + objname = obj->name ? obj->name : "vmlinux"; + + /* See livepatch core code for BUILD_BUG_ON() explanation */ + BUILD_BUG_ON(MODULE_NAME_LEN < 56 || KSYM_NAME_LEN != 128); + + for (s = info->sechdrs; s < info->sechdrs + info->hdr.e_shnum; s++) { + /* Apply per-object .klp.arch sections */ + cnt = sscanf(info->secstrings + s->sh_name, + ".klp.arch.%55[^.].%127s", + sec_objname, secname); + if (cnt != 2) + continue; + if (strcmp(sec_objname, objname)) + continue; + if (!strcmp(".altinstructions", secname)) + alt = s; + if (!strcmp(".parainstructions", secname)) + para = s; + } + + if (alt) { + aseg = (void *) alt->sh_addr; + apply_alternatives(aseg, aseg + alt->sh_size); + } + + if (para) { + pseg = (void *) para->sh_addr; + apply_paravirt(pseg, pseg + para->sh_size); + } +} From 5ad75fcdd712d18b393c3b3fe52ab4108703d337 Mon Sep 17 00:00:00 2001 From: Jessica Yu Date: Wed, 17 Aug 2016 20:58:30 -0400 Subject: [PATCH 3/4] Documentation: livepatch: add section about arch-specific code Document usage of arch-specific elf sections in livepatch as well as implementation of arch-specific code. [jkosina@suse.cz: fix wording as suggested by Petr Mladek] Signed-off-by: Jessica Yu Reviewed-by: Petr Mladek Signed-off-by: Jiri Kosina --- Documentation/livepatch/module-elf-format.txt | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/Documentation/livepatch/module-elf-format.txt b/Documentation/livepatch/module-elf-format.txt index eedbdcf8ba50..f21a5289a09c 100644 --- a/Documentation/livepatch/module-elf-format.txt +++ b/Documentation/livepatch/module-elf-format.txt @@ -25,7 +25,8 @@ Table of Contents 3.3.2 Required name format 3.3.3 Example livepatch symbol names 3.3.4 Example `readelf --symbols` output -4. Symbol table and Elf section access +4. Architecture-specific sections +5. Symbol table and Elf section access ---------------------------- 0. Background and motivation @@ -46,7 +47,7 @@ architecture. Since apply_relocate_add() requires access to a module's section header table, symbol table, and relocation section indices, Elf information is -preserved for livepatch modules (see section 4). Livepatch manages its own +preserved for livepatch modules (see section 5). Livepatch manages its own relocation sections and symbols, which are described in this document. The Elf constants used to mark livepatch symbols and relocation sections were selected from OS-specific ranges according to the definitions from glibc. @@ -117,7 +118,7 @@ also possible for a livepatch module to have no livepatch relocation sections, as in the case of the sample livepatch module (see samples/livepatch). -Since Elf information is preserved for livepatch modules (see Section 4), a +Since Elf information is preserved for livepatch modules (see Section 5), a livepatch relocation section can be applied simply by passing in the appropriate section index to apply_relocate_add(), which then uses it to access the relocation section and apply the relocations. @@ -292,8 +293,19 @@ Symbol table '.symtab' contains 127 entries: [*] Note that the 'Ndx' (Section index) for these symbols is SHN_LIVEPATCH (0xff20). "OS" means OS-specific. +--------------------------------- +4. Architecture-specific sections +--------------------------------- +Architectures may override arch_klp_init_object_loaded() to perform +additional arch-specific tasks when a target module loads, such as applying +arch-specific sections. On x86 for example, we must apply per-object +.altinstructions and .parainstructions sections when a target module loads. +These sections must be prefixed with ".klp.arch.$objname." so that they can +be easily identified when iterating through a patch module's Elf sections +(See arch/x86/kernel/livepatch.c for a complete example). + -------------------------------------- -4. Symbol table and Elf section access +5. Symbol table and Elf section access -------------------------------------- A livepatch module's symbol table is accessible through module->symtab. From 2992ef29ae01af998399d55ed7c692a2505fb8af Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 25 Aug 2016 10:04:45 -0500 Subject: [PATCH 4/4] livepatch/module: make TAINT_LIVEPATCH module-specific There's no reliable way to determine which module tainted the kernel with TAINT_LIVEPATCH. For example, /sys/module//taint doesn't report it. Neither does the "mod -t" command in the crash tool. Make it crystal clear who the guilty party is by associating TAINT_LIVEPATCH with any module which sets the "livepatch" modinfo attribute. The flag will still get set in the kernel like before, but now it also sets the same flag in mod->taint. Note that now the taint flag gets set when the module is loaded rather than when it's enabled. I also renamed find_livepatch_modinfo() to check_modinfo_livepatch() to better reflect its purpose: it's basically a livepatch-specific sub-function of check_modinfo(). Reported-by: Chunyu Hu Reviewed-by: Petr Mladek Acked-by: Miroslav Benes Acked-by: Jessica Yu Acked-by: Rusty Russell Signed-off-by: Josh Poimboeuf Signed-off-by: Jiri Kosina --- kernel/livepatch/core.c | 3 --- kernel/module.c | 13 +++++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 5fbabe022286..af4643873e71 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -545,9 +545,6 @@ static int __klp_enable_patch(struct klp_patch *patch) list_prev_entry(patch, list)->state == KLP_DISABLED) return -EBUSY; - pr_notice_once("tainting kernel with TAINT_LIVEPATCH\n"); - add_taint(TAINT_LIVEPATCH, LOCKDEP_STILL_OK); - pr_notice("enabling patch '%s'\n", patch->mod->name); klp_for_each_object(patch, obj) { diff --git a/kernel/module.c b/kernel/module.c index 529efae9f481..f57dd63186e6 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1149,6 +1149,8 @@ static size_t module_flags_taint(struct module *mod, char *buf) buf[l++] = 'C'; if (mod->taints & (1 << TAINT_UNSIGNED_MODULE)) buf[l++] = 'E'; + if (mod->taints & (1 << TAINT_LIVEPATCH)) + buf[l++] = 'K'; /* * TAINT_FORCED_RMMOD: could be added. * TAINT_CPU_OUT_OF_SPEC, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't @@ -2792,14 +2794,17 @@ static int copy_chunked_from_user(void *dst, const void __user *usrc, unsigned l } #ifdef CONFIG_LIVEPATCH -static int find_livepatch_modinfo(struct module *mod, struct load_info *info) +static int check_modinfo_livepatch(struct module *mod, struct load_info *info) { - mod->klp = get_modinfo(info, "livepatch") ? true : false; + if (get_modinfo(info, "livepatch")) { + mod->klp = true; + add_taint_module(mod, TAINT_LIVEPATCH, LOCKDEP_STILL_OK); + } return 0; } #else /* !CONFIG_LIVEPATCH */ -static int find_livepatch_modinfo(struct module *mod, struct load_info *info) +static int check_modinfo_livepatch(struct module *mod, struct load_info *info) { if (get_modinfo(info, "livepatch")) { pr_err("%s: module is marked as livepatch module, but livepatch support is disabled", @@ -2969,7 +2974,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags) "is unknown, you have been warned.\n", mod->name); } - err = find_livepatch_modinfo(mod, info); + err = check_modinfo_livepatch(mod, info); if (err) return err;