From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751608AbbDLNVd (ORCPT ); Sun, 12 Apr 2015 09:21:33 -0400 Received: from blu004-omc4s22.hotmail.com ([65.55.111.161]:56325 "EHLO BLU004-OMC4S22.hotmail.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751152AbbDLNVb (ORCPT ); Sun, 12 Apr 2015 09:21:31 -0400 X-Greylist: delayed 317 seconds by postgrey-1.27 at vger.kernel.org; Sun, 12 Apr 2015 09:21:31 EDT X-TMN: [zEnfcsKYexTKb3vaQNvLF7DFVEoOVePn] X-Originating-Email: [minfei.huang@hotmail.com] Message-ID: From: Minfei Huang To: jpoimboe@redhat.com, sjenning@redhat.com, jkosina@suse.cz, vojtech@suse.cz CC: live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, Minfei Huang Subject: [PATCH 1/2] livepatch: Add a new function to verify the address and name match for extra module Date: Sun, 12 Apr 2015 21:15:53 +0800 X-Mailer: git-send-email 2.2.2 In-Reply-To: <1428844554-4015-1-git-send-email-minfei.huang@hotmail.com> References: <1428844554-4015-1-git-send-email-minfei.huang@hotmail.com> X-OriginalArrivalTime: 12 Apr 2015 13:16:24.0941 (UTC) FILETIME=[E07D99D0:01D07522] MIME-Version: 1.0 Content-Type: text/plain Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In order to restrict the patch, we can verify the provided function address and name match. Now we have can only verify the vmlinux function name and address. Add a new function to verify extra module function name and address. The patch would not be patched, if the function name and address are not matched. Signed-off-by: Minfei Huang --- kernel/livepatch/core.c | 54 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 3f9f1d6..ff42c29 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -196,12 +196,16 @@ static int klp_find_object_symbol(const char *objname, const char *name, } struct klp_verify_args { + const char *objname; const char *name; const unsigned long addr; }; -static int klp_verify_callback(void *data, const char *name, - struct module *mod, unsigned long addr) +typedef int (*klp_verify_callback)(void *data, const char *name, + struct module *mod, unsigned long addr); + +static int klp_verify_vmlinux_callback(void *data, const char *name, + struct module *mod, unsigned long addr) { struct klp_verify_args *args = data; @@ -213,18 +217,38 @@ static int klp_verify_callback(void *data, const char *name, return 0; } -static int klp_verify_vmlinux_symbol(const char *name, unsigned long addr) +static int klp_verify_module_callback(void *data, const char *name, + struct module *mod, unsigned long addr) +{ + struct klp_verify_args *args = data; + + if (!mod || !args->objname) + return 0; + + if (!strcmp(args->objname, mod->name) && + !strcmp(args->name, name) && + args->addr == addr) + return 1; + + return 0; +} + +static int klp_verify_symbol(const char *objname, const char *name, + unsigned long addr) { struct klp_verify_args args = { + .objname = objname, .name = name, .addr = addr, }; + klp_verify_callback fn = objname ? + klp_verify_module_callback : klp_verify_vmlinux_callback; - if (kallsyms_on_each_symbol(klp_verify_callback, &args)) + if (kallsyms_on_each_symbol(fn, &args)) return 0; - pr_err("symbol '%s' not found at specified address 0x%016lx, kernel mismatch?\n", - name, addr); + pr_err("symbol '%s' not found at specified address 0x%016lx, %s mismatch?\n", + name, addr, objname ? objname : "kernel"); return -EINVAL; } @@ -238,12 +262,12 @@ static int klp_find_verify_func_addr(struct klp_object *obj, func->old_addr = 0; #endif - if (!func->old_addr || klp_is_module(obj)) - ret = klp_find_object_symbol(obj->name, func->old_name, - &func->old_addr); + if (func->old_addr) + ret = klp_verify_symbol(obj->name, func->old_name, + func->old_addr); else - ret = klp_verify_vmlinux_symbol(func->old_name, - func->old_addr); + ret = klp_find_object_symbol(obj->name, func->old_name, + &func->old_addr); return ret; } @@ -285,10 +309,8 @@ static int klp_write_object_relocations(struct module *pmod, for (reloc = obj->relocs; reloc->name; reloc++) { if (!klp_is_module(obj)) { - ret = klp_verify_vmlinux_symbol(reloc->name, + ret = klp_verify_symbol(NULL, reloc->name, reloc->val); - if (ret) - return ret; } else { /* module, reloc->val needs to be discovered */ if (reloc->external) @@ -299,9 +321,9 @@ static int klp_write_object_relocations(struct module *pmod, ret = klp_find_object_symbol(obj->mod->name, reloc->name, &reloc->val); - if (ret) - return ret; } + if (ret) + return ret; ret = klp_write_module_reloc(pmod, reloc->type, reloc->loc, reloc->val + reloc->addend); if (ret) { -- 2.2.2