lkml.org 
[lkml]   [2015]   [Apr]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 1/2] livepatch: Add a new function to verify the address and name match for extra module
Date
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 <minfei.huang@hotmail.com>
---
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


\
 
 \ /
  Last update: 2015-04-12 16:01    [W:0.100 / U:0.108 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site