mirror of
https://github.com/dynup/kpatch
synced 2025-05-03 08:27:57 +00:00
kmod/core: protect kpatch_[un]register with mutex
Use a mutex in the register/unregister functions to protect changes to kpatch_num_registered, kpatch_func_hash and calls to the ftrace functions by other register/unregister invocations.
This commit is contained in:
parent
ae6fce2cd9
commit
37a756af58
@ -48,6 +48,8 @@
|
|||||||
#define KPATCH_HASH_BITS 8
|
#define KPATCH_HASH_BITS 8
|
||||||
DEFINE_HASHTABLE(kpatch_func_hash, KPATCH_HASH_BITS);
|
DEFINE_HASHTABLE(kpatch_func_hash, KPATCH_HASH_BITS);
|
||||||
|
|
||||||
|
DEFINE_SEMAPHORE(kpatch_mutex);
|
||||||
|
|
||||||
static int kpatch_num_registered;
|
static int kpatch_num_registered;
|
||||||
|
|
||||||
struct kpatch_backtrace_args {
|
struct kpatch_backtrace_args {
|
||||||
@ -209,6 +211,8 @@ int kpatch_register(struct module *mod, struct kpatch_func *funcs,
|
|||||||
.num_funcs = num_funcs,
|
.num_funcs = num_funcs,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
down(&kpatch_mutex);
|
||||||
|
|
||||||
for (i = 0; i < num_funcs; i++) {
|
for (i = 0; i < num_funcs; i++) {
|
||||||
struct kpatch_func *func = &funcs[i];
|
struct kpatch_func *func = &funcs[i];
|
||||||
|
|
||||||
@ -225,7 +229,7 @@ int kpatch_register(struct module *mod, struct kpatch_func *funcs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Register the ftrace trampoline if it hasn't been done already. */
|
/* Register the ftrace trampoline if it hasn't been done already. */
|
||||||
if (!kpatch_num_registered++) { /* TODO atomic */
|
if (!kpatch_num_registered++) {
|
||||||
ret = register_ftrace_function(&kpatch_ftrace_ops);
|
ret = register_ftrace_function(&kpatch_ftrace_ops);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk("kpatch: can't register ftrace function \n");
|
printk("kpatch: can't register ftrace function \n");
|
||||||
@ -252,6 +256,7 @@ int kpatch_register(struct module *mod, struct kpatch_func *funcs,
|
|||||||
pr_notice("loaded patch module \"%s\"\n", mod->name);
|
pr_notice("loaded patch module \"%s\"\n", mod->name);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
up(&kpatch_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(kpatch_register);
|
EXPORT_SYMBOL(kpatch_register);
|
||||||
@ -265,6 +270,8 @@ int kpatch_unregister(struct module *mod, struct kpatch_func *funcs,
|
|||||||
.num_funcs = num_funcs,
|
.num_funcs = num_funcs,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
down(&kpatch_mutex);
|
||||||
|
|
||||||
ret = stop_machine(kpatch_remove_patch, &args, NULL);
|
ret = stop_machine(kpatch_remove_patch, &args, NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
@ -293,6 +300,7 @@ int kpatch_unregister(struct module *mod, struct kpatch_func *funcs,
|
|||||||
pr_notice("unloaded patch module \"%s\"\n", mod->name);
|
pr_notice("unloaded patch module \"%s\"\n", mod->name);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
up(&kpatch_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(kpatch_unregister);
|
EXPORT_SYMBOL(kpatch_unregister);
|
||||||
|
Loading…
Reference in New Issue
Block a user