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()
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user