On Thu, Jul 10, 2025 at 12:10 AM Menglong Dong <menglong8.dong@xxxxxxxxx> wrote: > > For now, we lookup the address of the attach target in > bpf_check_attach_target() with find_kallsyms_symbol_value or > kallsyms_lookup_name, which is not accurate in some cases. > > For example, we want to attach to the target "t_next", but there are > multiple symbols with the name "t_next" exist in the kallsyms, which makes > the attach target ambiguous, and the attach should fail. > > Introduce the function bpf_lookup_attach_addr() to do the address lookup, > which will return -EADDRNOTAVAIL when the symbol is not unique. > > We can do the testing with following shell: > > for s in $(cat /proc/kallsyms | awk '{print $3}' | sort | uniq -d) > do > if grep -q "^$s\$" /sys/kernel/debug/tracing/available_filter_functions > then > bpftrace -e "fentry:$s {printf(\"1\");}" -v > fi > done > > The script will find all the duplicated symbols in /proc/kallsyms, which > is also in /sys/kernel/debug/tracing/available_filter_functions, and > attach them with bpftrace. > > After this patch, all the attaching fail with the error: > > The address of function xxx cannot be found > or > No BTF found for xxx > > Signed-off-by: Menglong Dong <dongml2@xxxxxxxxxxxxxxx> > --- > v3: > - reject all the duplicated symbols > v2: > - Lookup both vmlinux and modules symbols when mod is NULL, just like > kallsyms_lookup_name(). > > If the btf is not a modules, shouldn't we lookup on the vmlinux only? > I'm not sure if we should keep the same logic with > kallsyms_lookup_name(). > > - Return the kernel symbol that don't have ftrace location if the symbols > with ftrace location are not available > --- > kernel/bpf/verifier.c | 71 ++++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 66 insertions(+), 5 deletions(-) > > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index 53007182b46b..bf4951154605 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -23476,6 +23476,67 @@ static int check_non_sleepable_error_inject(u32 btf_id) > return btf_id_set_contains(&btf_non_sleepable_error_inject, btf_id); > } > > +struct symbol_lookup_ctx { > + const char *name; > + unsigned long addr; > +}; > + > +static int symbol_callback(void *data, unsigned long addr) > +{ > + struct symbol_lookup_ctx *ctx = data; > + > + if (ctx->addr) > + return -EADDRNOTAVAIL; #define ENOTUNIQ 76 /* Name not unique on network */ fits a bit better, no? > + ctx->addr = addr; > + > + return 0; > +} > + [...]