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

Commit b4da3340 authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Alexei Starovoitov
Browse files

tracing/kprobe: bpf: Check error injectable event is on function entry



Check whether error injectable event is on function entry or not.
Currently it checks the event is ftrace-based kprobes or not,
but that is wrong. It should check if the event is on the entry
of target function. Since error injection will override a function
to just return with modified return value, that operation must
be done before the target function starts making stackframe.

As a side effect, bpf error injection is no need to depend on
function-tracer. It can work with sw-breakpoint based kprobe
events too.

Signed-off-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
Reviewed-by: default avatarJosef Bacik <jbacik@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent daaf24c6
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -67,9 +67,7 @@ extern const int kretprobe_blacklist_size;
void arch_remove_kprobe(struct kprobe *p);
asmlinkage void kretprobe_trampoline(void);

#ifdef CONFIG_KPROBES_ON_FTRACE
extern void arch_ftrace_kprobe_override_function(struct pt_regs *regs);
#endif
extern void arch_kprobe_override_function(struct pt_regs *regs);

/* Architecture specific copy of original instruction*/
struct arch_specific_insn {
+14 −0
Original line number Diff line number Diff line
@@ -1183,3 +1183,17 @@ int arch_trampoline_kprobe(struct kprobe *p)
{
	return 0;
}

asmlinkage void override_func(void);
asm(
	".type override_func, @function\n"
	"override_func:\n"
	"	ret\n"
	".size override_func, .-override_func\n"
);

void arch_kprobe_override_function(struct pt_regs *regs)
{
	regs->ip = (unsigned long)&override_func;
}
NOKPROBE_SYMBOL(arch_kprobe_override_function);
+0 −14
Original line number Diff line number Diff line
@@ -97,17 +97,3 @@ int arch_prepare_kprobe_ftrace(struct kprobe *p)
	p->ainsn.boostable = false;
	return 0;
}

asmlinkage void override_func(void);
asm(
	".type override_func, @function\n"
	"override_func:\n"
	"	ret\n"
	".size override_func, .-override_func\n"
);

void arch_ftrace_kprobe_override_function(struct pt_regs *regs)
{
	regs->ip = (unsigned long)&override_func;
}
NOKPROBE_SYMBOL(arch_ftrace_kprobe_override_function);
+0 −2
Original line number Diff line number Diff line
@@ -533,9 +533,7 @@ config FUNCTION_PROFILER
config BPF_KPROBE_OVERRIDE
	bool "Enable BPF programs to override a kprobed function"
	depends on BPF_EVENTS
	depends on KPROBES_ON_FTRACE
	depends on HAVE_KPROBE_OVERRIDE
	depends on DYNAMIC_FTRACE_WITH_REGS
	default n
	help
	 Allows BPF to override the execution of a probed function and
+4 −4
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ BPF_CALL_2(bpf_override_return, struct pt_regs *, regs, unsigned long, rc)
{
	__this_cpu_write(bpf_kprobe_override, 1);
	regs_set_return_value(regs, rc);
	arch_ftrace_kprobe_override_function(regs);
	arch_kprobe_override_function(regs);
	return 0;
}

@@ -800,11 +800,11 @@ int perf_event_attach_bpf_prog(struct perf_event *event,
	int ret = -EEXIST;

	/*
	 * Kprobe override only works for ftrace based kprobes, and only if they
	 * are on the opt-in list.
	 * Kprobe override only works if they are on the function entry,
	 * and only if they are on the opt-in list.
	 */
	if (prog->kprobe_override &&
	    (!trace_kprobe_ftrace(event->tp_event) ||
	    (!trace_kprobe_on_func_entry(event->tp_event) ||
	     !trace_kprobe_error_injectable(event->tp_event)))
		return -EINVAL;

Loading