From 8458c8bb21afd82ff19848bdb5c06b474d5988d1 Mon Sep 17 00:00:00 2001 From: Hengqi Chen Date: Sat, 26 Mar 2022 22:43:20 +0800 Subject: [PATCH] libbpf: Allow kprobe attach using legacy debugfs interface On some old kernels, kprobe auto-attach may fail when attach to symbols like udp_send_skb.isra.52 . This is because the kernel has kprobe PMU but don't allow attach to a symbol with '.' ([0]). Add a new option to bpf_kprobe_opts to allow using the legacy kprobe attach directly. This way, users can use bpf_program__attach_kprobe_opts in a dedicated custom sec handler to handle such case. [0]: https://github.com/torvalds/linux/blob/v4.18/kernel/trace/trace_kprobe.c#L340-L343 Signed-off-by: Hengqi Chen --- tools/lib/bpf/libbpf.c | 9 ++++++++- tools/lib/bpf/libbpf.h | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 809fe209cdcc0..9a294bb84badd 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -10097,9 +10097,16 @@ static void gen_kprobe_legacy_event_name(char *buf, size_t buf_sz, const char *kfunc_name, size_t offset) { static int index = 0; + int i; snprintf(buf, buf_sz, "libbpf_%u_%s_0x%zx_%d", getpid(), kfunc_name, offset, __sync_fetch_and_add(&index, 1)); + + /* sanitize .isra.$n symbols */ + for (i = 0; buf[i]; i++) { + if (!isalnum(buf[i])) + buf[i] = '_'; + } } static int add_kprobe_event_legacy(const char *probe_name, bool retprobe, @@ -10189,7 +10196,7 @@ bpf_program__attach_kprobe_opts(const struct bpf_program *prog, offset = OPTS_GET(opts, offset, 0); pe_opts.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0); - legacy = determine_kprobe_perf_type() < 0; + legacy = OPTS_GET(opts, legacy, false) || determine_kprobe_perf_type() < 0; if (!legacy) { pfd = perf_event_open_probe(false /* uprobe */, retprobe, func_name, offset, diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 05dde85e19a6f..88a3624e3f15d 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -413,9 +413,11 @@ struct bpf_kprobe_opts { size_t offset; /* kprobe is return probe */ bool retprobe; + /* use the legacy debugfs interface */ + bool legacy; size_t :0; }; -#define bpf_kprobe_opts__last_field retprobe +#define bpf_kprobe_opts__last_field legacy LIBBPF_API struct bpf_link * bpf_program__attach_kprobe(const struct bpf_program *prog, bool retprobe,