jump label: Fix deadlock b/w jump_label_mutex vs. text_mutex

register_kprobe() downs the 'text_mutex' and then calls
jump_label_text_reserved(), which downs the 'jump_label_mutex'.
However, the jump label code takes those mutexes in the reverse
order.

Fix by requiring the caller of jump_label_text_reserved() to do
the jump label locking via the newly added: jump_label_lock(),
jump_label_unlock(). Currently, kprobes is the only user
of jump_label_text_reserved().

Reported-by: Ingo Molnar <[email protected]>
Acked-by: Masami Hiramatsu <[email protected]>
Signed-off-by: Jason Baron <[email protected]>
LKML-Reference: <759032c48d5e30c27f0bba003d09bffa8e9f28bb.1285965957.git.jbaron@redhat.com>
Signed-off-by: Steven Rostedt <[email protected]>
This commit is contained in:
Jason Baron 2010-10-01 17:23:48 -04:00 • committed by Steven Rostedt
commit 91bad2f8d3
3 changed files with 32 additions and 12 deletions

View file

@ -1146,13 +1146,16 @@ int __kprobes register_kprobe(struct kprobe *p)
return ret;
preempt_disable();
jump_label_lock();
if (!kernel_text_address((unsigned long) p->addr) ||
in_kprobes_functions((unsigned long) p->addr) ||
ftrace_text_reserved(p->addr, p->addr) ||
jump_label_text_reserved(p->addr, p->addr)) {
preempt_enable();
jump_label_unlock();
return -EINVAL;
}
jump_label_unlock();
/* User can pass only KPROBE_FLAG_DISABLED to register_kprobe */
p->flags &= KPROBE_FLAG_DISABLED;
@ -1187,6 +1190,8 @@ int __kprobes register_kprobe(struct kprobe *p)
INIT_LIST_HEAD(&p->list);
mutex_lock(&kprobe_mutex);
jump_label_lock(); /* needed to call jump_label_text_reserved() */
get_online_cpus(); /* For avoiding text_mutex deadlock. */
mutex_lock(&text_mutex);
@ -1214,6 +1219,7 @@ int __kprobes register_kprobe(struct kprobe *p)
out:
mutex_unlock(&text_mutex);
put_online_cpus();
jump_label_unlock();
mutex_unlock(&kprobe_mutex);
if (probed_mod)