mirror of
https://github.com/dynup/kpatch
synced 2025-04-01 22:48:08 +00:00
fix activeness safety check when unpatching
When unpatching, the activeness safety logic should check for the new function on the stack, not the old one. Fixes #64.
This commit is contained in:
parent
48cc3a409e
commit
f3f39c0587
@ -118,12 +118,24 @@ void kpatch_backtrace_address_verify(void *data, unsigned long address,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < kpmod->num_funcs; i++) {
|
for (i = 0; i < kpmod->num_funcs; i++) {
|
||||||
struct kpatch_func *func = &kpmod->funcs[i];
|
unsigned long func_addr, func_size;
|
||||||
|
struct kpatch_func *func, *active_func;
|
||||||
|
|
||||||
if (address >= func->old_addr &&
|
func = &kpmod->funcs[i];
|
||||||
address < func->old_addr + func->old_size) {
|
active_func = kpatch_get_func(func->old_addr);
|
||||||
|
if (!active_func) {
|
||||||
|
/* patching an unpatched func */
|
||||||
|
func_addr = func->old_addr;
|
||||||
|
func_size = func->old_size;
|
||||||
|
} else {
|
||||||
|
/* repatching or unpatching */
|
||||||
|
func_addr = active_func->new_addr;
|
||||||
|
func_size = active_func->new_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (address >= func_addr && address < func_addr + func_size) {
|
||||||
pr_err("activeness safety check failed for function "
|
pr_err("activeness safety check failed for function "
|
||||||
"at address 0x%lx\n", func->old_addr);
|
"at address 0x%lx\n", func_addr);
|
||||||
args->ret = -EBUSY;
|
args->ret = -EBUSY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
struct kpatch_func {
|
struct kpatch_func {
|
||||||
unsigned long new_addr;
|
unsigned long new_addr;
|
||||||
|
unsigned long new_size;
|
||||||
unsigned long old_addr;
|
unsigned long old_addr;
|
||||||
unsigned long old_size;
|
unsigned long old_size;
|
||||||
struct hlist_node node;
|
struct hlist_node node;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2013 Josh Poimboeuf <jpoimboe@redhat.com>
|
* Copyright (C) 2013-2014 Josh Poimboeuf <jpoimboe@redhat.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -48,6 +48,7 @@ static int __init patch_init(void)
|
|||||||
kpmod.funcs[i].old_addr = patches[i].old_addr;
|
kpmod.funcs[i].old_addr = patches[i].old_addr;
|
||||||
kpmod.funcs[i].old_size = patches[i].old_size;
|
kpmod.funcs[i].old_size = patches[i].old_size;
|
||||||
kpmod.funcs[i].new_addr = patches[i].new_addr;
|
kpmod.funcs[i].new_addr = patches[i].new_addr;
|
||||||
|
kpmod.funcs[i].new_size = patches[i].new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = kpatch_register(&kpmod);
|
ret = kpatch_register(&kpmod);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
struct kpatch_patch {
|
struct kpatch_patch {
|
||||||
unsigned long new_addr;
|
unsigned long new_addr;
|
||||||
|
unsigned long new_size;
|
||||||
unsigned long old_addr;
|
unsigned long old_addr;
|
||||||
unsigned long old_size;
|
unsigned long old_size;
|
||||||
};
|
};
|
||||||
|
@ -315,10 +315,18 @@ int main(int argc, char **argv)
|
|||||||
for_each_sym(&symlist, cur) {
|
for_each_sym(&symlist, cur) {
|
||||||
if (cur->action != PATCH)
|
if (cur->action != PATCH)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
patches_data[i].old_addr = cur->vm_addr;
|
patches_data[i].old_addr = cur->vm_addr;
|
||||||
patches_data[i].old_size = cur->vm_len;
|
patches_data[i].old_size = cur->vm_len;
|
||||||
|
patches_data[i].new_size = cur->sym.st_size;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use a relocation to set patches_data[i].new_addr at module
|
||||||
|
* loading time.
|
||||||
|
*/
|
||||||
relas_data[i].r_offset = i * sizeof(struct kpatch_patch);
|
relas_data[i].r_offset = i * sizeof(struct kpatch_patch);
|
||||||
relas_data[i].r_info = GELF_R_INFO(cur->index, R_X86_64_64);
|
relas_data[i].r_info = GELF_R_INFO(cur->index, R_X86_64_64);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user