From 37a756af580f7066b18f60b2693c41604e3268b9 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Wed, 19 Mar 2014 10:01:29 -0500 Subject: [PATCH] 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. --- kmod/core/core.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kmod/core/core.c b/kmod/core/core.c index db82ebb..225c227 100644 --- a/kmod/core/core.c +++ b/kmod/core/core.c @@ -48,6 +48,8 @@ #define KPATCH_HASH_BITS 8 DEFINE_HASHTABLE(kpatch_func_hash, KPATCH_HASH_BITS); +DEFINE_SEMAPHORE(kpatch_mutex); + static int kpatch_num_registered; struct kpatch_backtrace_args { @@ -209,6 +211,8 @@ int kpatch_register(struct module *mod, struct kpatch_func *funcs, .num_funcs = num_funcs, }; + down(&kpatch_mutex); + for (i = 0; i < num_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. */ - if (!kpatch_num_registered++) { /* TODO atomic */ + if (!kpatch_num_registered++) { ret = register_ftrace_function(&kpatch_ftrace_ops); if (ret) { 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); out: + up(&kpatch_mutex); return ret; } EXPORT_SYMBOL(kpatch_register); @@ -265,6 +270,8 @@ int kpatch_unregister(struct module *mod, struct kpatch_func *funcs, .num_funcs = num_funcs, }; + down(&kpatch_mutex); + ret = stop_machine(kpatch_remove_patch, &args, NULL); if (ret) 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); out: + up(&kpatch_mutex); return ret; } EXPORT_SYMBOL(kpatch_unregister);