From 2137a1eb829e3431b044df87a32dbff4ab8784a7 Mon Sep 17 00:00:00 2001 From: Cheng Jian Date: Mon, 1 Jul 2019 09:50:04 +0800 Subject: [PATCH] livepatch/arm64: fix arch specific alternative section hulk inclusion category: bugfix bugzilla: 5507 CVE: NA ---------------------------------------------- Override arch_klp_init_object_loaded() to perform additional arch-specific tasks when a target module loads, such as applying arch-specific sections. On arm64, we must apply per-object .altinstructions sections when a target module loads. These sections are prefixed with ".klp.arch.$objname.$secname", so that they can be easily identified when iterating through a patch module's Elf sections. Fix next calltrace: livepatch: enabling patch 'livepatch_0001_test_per_cpu_cmdline' Unable to handle kernel paging request at virtual address ffff34dc4663e018 pc : cmdline_proc_show+0x24/0xc40 [livepatch_0001_test_per_cpu_cmdline] lr : seq_read+0xd4/0x4a8 sp : ffff0000d0a73c30 Call trace: cmdline_proc_show+0x24/0xc40 [livepatch_0001_test_per_cpu_cmdline] seq_read+0xd4/0x4a8 proc_reg_read+0x80/0xd8 __vfs_read+0x60/0x188 vfs_read+0x94/0x150 ksys_read+0x74/0xf0 __arm64_sys_read+0x24/0x30 el0_svc_common+0xa0/0x180 el0_svc_handler+0x38/0x78 el0_svc+0x8/0xc Code: d503201f f0274aa2 91006042 d538d083 (b8636842) ---[ end trace 1256914246c5a0cf ]--- Testcase livepatch code: fs/proc/cmdline.c static int cmdline_proc_show(struct seq_file *m, void *v) { + seq_printf(m, "[%d] ", raw_smp_processor_id()); seq_puts(m, saved_command_line); seq_putc(m, '\n'); return 0; } Signed-off-by: Cheng Jian Reviewed-by: Bin Li Signed-off-by: Yang Yingliang --- arch/arm64/kernel/livepatch.c | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/arch/arm64/kernel/livepatch.c b/arch/arm64/kernel/livepatch.c index c419fb0a90e6..49f0a79309bd 100644 --- a/arch/arm64/kernel/livepatch.c +++ b/arch/arm64/kernel/livepatch.c @@ -344,3 +344,42 @@ int arch_klp_func_can_patch(struct klp_func *func) } #endif /* #ifdef CONFIG_ARM64_MODULE_PLTS */ #endif + + +/* Apply per-object alternatives. Based on arm64 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; + void *aseg; + 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 (alt) { + aseg = (void *) alt->sh_addr; + apply_alternatives_module(aseg, alt->sh_size); + } +} -- GitLab