Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 201517a7 authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Linus Torvalds
Browse files

kprobes: fix to use text_mutex around arm/disarm kprobe



Fix kprobes to lock text_mutex around some arch_arm/disarm_kprobe() which
are newly added by commit de5bd88d.

Signed-off-by: default avatarMasami Hiramatsu <mhiramat@redhat.com>
Acked-by: default avatarAnanth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent d7a59269
Loading
Loading
Loading
Loading
+22 −9
Original line number Diff line number Diff line
@@ -319,6 +319,22 @@ struct kprobe __kprobes *get_kprobe(void *addr)
	return NULL;
}

/* Arm a kprobe with text_mutex */
static void __kprobes arm_kprobe(struct kprobe *kp)
{
	mutex_lock(&text_mutex);
	arch_arm_kprobe(kp);
	mutex_unlock(&text_mutex);
}

/* Disarm a kprobe with text_mutex */
static void __kprobes disarm_kprobe(struct kprobe *kp)
{
	mutex_lock(&text_mutex);
	arch_disarm_kprobe(kp);
	mutex_unlock(&text_mutex);
}

/*
 * Aggregate handlers for multiple kprobes support - these handlers
 * take care of invoking the individual kprobe handlers on p->list
@@ -538,7 +554,7 @@ static int __kprobes add_new_kprobe(struct kprobe *ap, struct kprobe *p)
		ap->flags &= ~KPROBE_FLAG_DISABLED;
		if (!kprobes_all_disarmed)
			/* Arm the breakpoint again. */
			arch_arm_kprobe(ap);
			arm_kprobe(ap);
	}
	return 0;
}
@@ -789,11 +805,8 @@ static int __kprobes __unregister_kprobe_top(struct kprobe *p)
		 * enabled and not gone - otherwise, the breakpoint would
		 * already have been removed. We save on flushing icache.
		 */
		if (!kprobes_all_disarmed && !kprobe_disabled(old_p)) {
			mutex_lock(&text_mutex);
			arch_disarm_kprobe(p);
			mutex_unlock(&text_mutex);
		}
		if (!kprobes_all_disarmed && !kprobe_disabled(old_p))
			disarm_kprobe(p);
		hlist_del_rcu(&old_p->hlist);
	} else {
		if (p->break_handler && !kprobe_gone(p))
@@ -810,7 +823,7 @@ noclean:
		if (!kprobe_disabled(old_p)) {
			try_to_disable_aggr_kprobe(old_p);
			if (!kprobes_all_disarmed && kprobe_disabled(old_p))
				arch_disarm_kprobe(old_p);
				disarm_kprobe(old_p);
		}
	}
	return 0;
@@ -1364,7 +1377,7 @@ int __kprobes disable_kprobe(struct kprobe *kp)
		try_to_disable_aggr_kprobe(p);

	if (!kprobes_all_disarmed && kprobe_disabled(p))
		arch_disarm_kprobe(p);
		disarm_kprobe(p);
out:
	mutex_unlock(&kprobe_mutex);
	return ret;
@@ -1393,7 +1406,7 @@ int __kprobes enable_kprobe(struct kprobe *kp)
	}

	if (!kprobes_all_disarmed && kprobe_disabled(p))
		arch_arm_kprobe(p);
		arm_kprobe(p);

	p->flags &= ~KPROBE_FLAG_DISABLED;
	if (p != kp)