review changes for module support PR

Signed-off-by: Seth Jennings <sjenning@redhat.com>
This commit is contained in:
Seth Jennings 2014-06-03 11:36:51 -05:00
parent 5b62d5f169
commit 15b22cf01b

View File

@ -473,15 +473,20 @@ static int kpatch_verify_symbol_match(char *name, unsigned long addr)
static unsigned long kpatch_find_module_symbol(struct module *mod, char *name) static unsigned long kpatch_find_module_symbol(struct module *mod, char *name)
{ {
char buf[255], *pos; char buf[KSYM_SYMBOL_LEN];
/* check total string length for overrun */
if (strlen(mod->name) + strlen(name) + 1 >= KSYM_SYMBOL_LEN) {
pr_err("buffer overrun finding symbol '%s' in module '%s'\n",
name, mod->name);
return 0;
}
/* encode symbol name as "mod->name:name" */ /* encode symbol name as "mod->name:name" */
strcpy(buf, mod->name); strcpy(buf, mod->name);
pos = buf + strlen(mod->name); strcat(buf, ":");
*pos++ = ':'; strcat(buf, name);
strcpy(pos, name);
pr_notice("looking up '%s'\n", buf);
return kallsyms_lookup_name(buf); return kallsyms_lookup_name(buf);
} }
@ -493,7 +498,7 @@ static int kpatch_write_relocations(struct kpatch_module *kpmod)
unsigned long core = (unsigned long)kpmod->mod->module_core; unsigned long core = (unsigned long)kpmod->mod->module_core;
unsigned long core_ro_size = kpmod->mod->core_ro_size; unsigned long core_ro_size = kpmod->mod->core_ro_size;
unsigned long core_size = kpmod->mod->core_size; unsigned long core_size = kpmod->mod->core_size;
unsigned long old_addr; unsigned long src_addr;
struct module *mod; struct module *mod;
for (i = 0; i < kpmod->dynrelas_nr; i++) { for (i = 0; i < kpmod->dynrelas_nr; i++) {
@ -504,17 +509,19 @@ static int kpatch_write_relocations(struct kpatch_module *kpmod)
ret = kpatch_verify_symbol_match(dynrela->name, dynrela->src); ret = kpatch_verify_symbol_match(dynrela->name, dynrela->src);
if (ret) if (ret)
return ret; return ret;
old_addr = dynrela->src; src_addr = dynrela->src;
} else { } else {
/* module, dynrela->src is not right */ /* module, dynrela->src is not right */
mod = find_module(dynrela->objname); mod = find_module(dynrela->objname);
if (!mod) { if (!mod) {
pr_err("unable to find module\n"); pr_err("unable to find module '%s'\n",
dynrela->objname);
return -EINVAL; return -EINVAL;
} }
old_addr = kpatch_find_module_symbol(mod, dynrela->name); src_addr = kpatch_find_module_symbol(mod, dynrela->name);
if (!old_addr) { if (!src_addr) {
pr_err("unable to find symbol\n"); pr_err("unable to find symbol '%s' in module '%s'\n",
dynrela->name, mod->name);
return -EINVAL; return -EINVAL;
} }
} }
@ -522,20 +529,20 @@ static int kpatch_write_relocations(struct kpatch_module *kpmod)
switch (dynrela->type) { switch (dynrela->type) {
case R_X86_64_PC32: case R_X86_64_PC32:
loc = dynrela->dest; loc = dynrela->dest;
val = (u32)(old_addr + dynrela->addend - val = (u32)(src_addr + dynrela->addend -
dynrela->dest); dynrela->dest);
size = 4; size = 4;
break; break;
case R_X86_64_32S: case R_X86_64_32S:
loc = dynrela->dest; loc = dynrela->dest;
val = (s32)old_addr + dynrela->addend; val = (s32)src_addr + dynrela->addend;
size = 4; size = 4;
break; break;
default: default:
printk("unsupported rela type %ld for " printk("unsupported rela type %ld for "
"0x%lx <- 0x%lx at index %d\n", "0x%lx <- 0x%lx at index %d\n",
dynrela->type, dynrela->dest, dynrela->type, dynrela->dest,
old_addr, i); src_addr, i);
return -EINVAL; return -EINVAL;
} }
@ -567,19 +574,18 @@ static int kpatch_write_relocations(struct kpatch_module *kpmod)
return 0; return 0;
} }
int kpatch_calculate_old_addr(struct kpatch_func *func) static int kpatch_calculate_old_addr(struct kpatch_func *func)
{ {
struct module *module; struct module *module;
if (!strcmp(func->patch->objname, "vmlinux")) { if (!strcmp(func->patch->objname, "vmlinux")) {
func->old_addr = func->patch->old_offset; func->old_addr = func->patch->old_offset;
func->mod = NULL;
return 0; return 0;
} }
module = find_module(func->patch->objname); module = find_module(func->patch->objname);
if (!module) { if (!module) {
pr_err("patch contains code for an module that is not loaded\n"); pr_err("patch contains code for a module that is not loaded\n");
return -EINVAL; return -EINVAL;
} }
@ -609,7 +615,7 @@ int kpatch_register(struct kpatch_module *kpmod, bool replace)
if (!kpmod->internal) if (!kpmod->internal)
return -ENOMEM; return -ENOMEM;
funcs = kmalloc(sizeof(*funcs) * num_funcs, GFP_KERNEL); funcs = kzalloc(sizeof(*funcs) * num_funcs, GFP_KERNEL);
if (!funcs) { if (!funcs) {
kfree(kpmod->internal); kfree(kpmod->internal);
return -ENOMEM; return -ENOMEM;