Skip to content

Commit

Permalink
kmod/core: fix replace race condition
Browse files Browse the repository at this point in the history
In the replace case, stop calling module_put on a patch module before
we're potentially done with it.

This will also be needed for future module patching if we want to
properly replace a patch module which only patches a future loaded
module (that's a mouthful).

Fixes #165.
  • Loading branch information
jpoimboe committed Jun 13, 2014
1 parent 2ec9a04 commit 052806f
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions kmod/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -707,20 +707,29 @@ int kpatch_register(struct kpatch_module *kpmod, bool replace)
* the ftrace filter, and disable the owning patch module so that it
* can be removed.
*/
if (!ret && replace)
if (!ret && replace) {
struct kpatch_module *kpmod2, *safe;

hash_for_each_rcu(kpatch_func_hash, i, func, node) {
if (func->op != KPATCH_OP_UNPATCH)
continue;
hash_del_rcu(&func->node);
WARN_ON(kpatch_ftrace_remove_func(func->old_addr));
if (func->kpmod->enabled) {
func->kpmod->enabled = false;
pr_notice("unloaded patch module '%s'\n",
func->kpmod->mod->name);
module_put(func->kpmod->mod);
}
}

list_for_each_entry_safe(kpmod2, safe, &kpmod_list, list) {
if (kpmod == kpmod2)
continue;

kpmod2->enabled = false;
pr_notice("unloaded patch module '%s'\n",
kpmod2->mod->name);
module_put(kpmod2->mod);
list_del(&kpmod2->list);
}
}


/* memory barrier between func hash and state write */
smp_wmb();

Expand Down

0 comments on commit 052806f

Please sign in to comment.