Commit 8d6bc6a2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'probes-fixes-v6.10-rc1' of...

Merge tag 'probes-fixes-v6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull probes fixes from Masami Hiramatsu:

 - uprobes: prevent mutex_lock() under rcu_read_lock().

   Recent changes moved uprobe_cpu_buffer preparation which involves
   mutex_lock(), under __uprobe_trace_func() which is called inside
   rcu_read_lock().

   Fix it by moving uprobe_cpu_buffer preparation outside of
   __uprobe_trace_func()

 - kprobe-events: handle the error case of btf_find_struct_member()

* tag 'probes-fixes-v6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  tracing/probes: fix error check in parse_btf_field()
  uprobes: prevent mutex_lock() under rcu_read_lock()
parents 2bfcfd58 e569eb34
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -554,6 +554,10 @@ static int parse_btf_field(char *fieldname, const struct btf_type *type,
			anon_offs = 0;
			field = btf_find_struct_member(ctx->btf, type, fieldname,
						       &anon_offs);
			if (IS_ERR(field)) {
				trace_probe_log_err(ctx->offset, BAD_BTF_TID);
				return PTR_ERR(field);
			}
			if (!field) {
				trace_probe_log_err(ctx->offset, NO_BTF_FIELD);
				return -ENOENT;
+9 −5
Original line number Diff line number Diff line
@@ -970,19 +970,17 @@ static struct uprobe_cpu_buffer *prepare_uprobe_buffer(struct trace_uprobe *tu,

static void __uprobe_trace_func(struct trace_uprobe *tu,
				unsigned long func, struct pt_regs *regs,
				struct uprobe_cpu_buffer **ucbp,
				struct uprobe_cpu_buffer *ucb,
				struct trace_event_file *trace_file)
{
	struct uprobe_trace_entry_head *entry;
	struct trace_event_buffer fbuffer;
	struct uprobe_cpu_buffer *ucb;
	void *data;
	int size, esize;
	struct trace_event_call *call = trace_probe_event_call(&tu->tp);

	WARN_ON(call != trace_file->event_call);

	ucb = prepare_uprobe_buffer(tu, regs, ucbp);
	if (WARN_ON_ONCE(ucb->dsize > PAGE_SIZE))
		return;

@@ -1014,13 +1012,16 @@ static int uprobe_trace_func(struct trace_uprobe *tu, struct pt_regs *regs,
			     struct uprobe_cpu_buffer **ucbp)
{
	struct event_file_link *link;
	struct uprobe_cpu_buffer *ucb;

	if (is_ret_probe(tu))
		return 0;

	ucb = prepare_uprobe_buffer(tu, regs, ucbp);

	rcu_read_lock();
	trace_probe_for_each_link_rcu(link, &tu->tp)
		__uprobe_trace_func(tu, 0, regs, ucbp, link->file);
		__uprobe_trace_func(tu, 0, regs, ucb, link->file);
	rcu_read_unlock();

	return 0;
@@ -1031,10 +1032,13 @@ static void uretprobe_trace_func(struct trace_uprobe *tu, unsigned long func,
				 struct uprobe_cpu_buffer **ucbp)
{
	struct event_file_link *link;
	struct uprobe_cpu_buffer *ucb;

	ucb = prepare_uprobe_buffer(tu, regs, ucbp);

	rcu_read_lock();
	trace_probe_for_each_link_rcu(link, &tu->tp)
		__uprobe_trace_func(tu, func, regs, ucbp, link->file);
		__uprobe_trace_func(tu, func, regs, ucb, link->file);
	rcu_read_unlock();
}