From: Eduard Zingerman <eddyz87@gmail.com>
To: Anton Protopopov <a.s.protopopov@gmail.com>,
Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: bpf <bpf@vger.kernel.org>, Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
Anton Protopopov <aspsk@isovalent.com>,
Daniel Borkmann <daniel@iogearbox.net>,
Quentin Monnet <qmo@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>
Subject: Re: [RFC bpf-next 8/9] libbpf: support llvm-generated indirect jumps
Date: Mon, 07 Jul 2025 16:45:24 -0700 [thread overview]
Message-ID: <e726d778a3cf75e3ceec54f5f43b9d5d66ba5e97.camel@gmail.com> (raw)
In-Reply-To: <aFLWaNSsV7M2gV98@mail.gmail.com>
On Wed, 2025-06-18 at 15:08 +0000, Anton Protopopov wrote:
> On 25/06/17 08:22PM, Alexei Starovoitov wrote:
> > On Sun, Jun 15, 2025 at 1:55 AM Anton Protopopov
> > <a.s.protopopov@gmail.com> wrote:
> > >
> > > The final line generates an indirect jump. The
> > > format of the indirect jump instruction supported by BPF is
> > >
> > > BPF_JMP|BPF_X|BPF_JA, SRC=0, DST=Rx, off=0, imm=fd(M)
> > >
> > > and, obviously, the map M must be the same map which was used to
> > > init the register rX. This patch implements this in the following,
> > > hacky, but so far suitable for all existing use-cases, way. On
> > > encountering a `gotox` instruction libbpf tracks back to the
> > > previous direct load from map and stores this map file descriptor
> > > in the gotox instruction.
> >
> > ...
> >
> > > +/*
> > > + * This one is too dumb, of course. TBD to make it smarter.
> > > + */
> > > +static int find_jt_map_fd(struct bpf_program *prog, int insn_idx)
> > > +{
> > > + struct bpf_insn *insn = &prog->insns[insn_idx];
> > > + __u8 dst_reg = insn->dst_reg;
> > > +
> > > + /* TBD: this function is such smart for now that it even ignores this
> > > + * register. Instead, it should backtrack the load more carefully.
> > > + * (So far even this dumb version works with all selftests.)
> > > + */
> > > + pr_debug("searching for a load instruction which populated dst_reg=r%u\n", dst_reg);
> > > +
> > > + while (--insn >= prog->insns) {
> > > + if (insn->code == (BPF_LD|BPF_DW|BPF_IMM))
> > > + return insn[0].imm;
> > > + }
> > > +
> > > + return -ENOENT;
> > > +}
> > > +
> > > +static int bpf_object__patch_gotox(struct bpf_object *obj, struct bpf_program *prog)
> > > +{
> > > + struct bpf_insn *insn = prog->insns;
> > > + int map_fd;
> > > + int i;
> > > +
> > > + for (i = 0; i < prog->insns_cnt; i++, insn++) {
> > > + if (!insn_is_gotox(insn))
> > > + continue;
> > > +
> > > + if (obj->gen_loader)
> > > + return -EFAULT;
> > > +
> > > + map_fd = find_jt_map_fd(prog, i);
> > > + if (map_fd < 0)
> > > + return map_fd;
> > > +
> > > + insn->imm = map_fd;
> > > + }
> >
> > This is obviously broken and cannot be made smarter in libbpf.
> > It won't be doing data flow analysis.
> >
> > The only option I see is to teach llvm to tag jmp_table in gotox.
> > Probably the simplest way is to add the same relo to gotox insn
> > as for ld_imm64. Then libbpf has a direct way to assign
> > the same map_fd into both ld_imm64 and gotox.
>
> This would be nice.
I did not implement this is a change for jt section + jt symbols.
It can be added, but thinking about it again, are you sure it is
necessary to have map fd in the gotox?
Verifier should be smart enough already to track what map the rX in
the `gotox rX` is a derivative of. It can make use of
bpf_insn_aux_data->map_index to enforce that only one map is used with
a particular gotox instruction.
[...]
next prev parent reply other threads:[~2025-07-07 23:45 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-15 8:59 [RFC bpf-next 0/9] BPF indirect jumps Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 1/9] bpf: save the start of functions in bpf_prog_aux Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 2/9] bpf, x86: add new map type: instructions set Anton Protopopov
2025-06-18 0:57 ` Eduard Zingerman
2025-06-18 2:16 ` Alexei Starovoitov
2025-06-19 18:57 ` Anton Protopopov
2025-06-19 18:55 ` Anton Protopopov
2025-06-19 18:55 ` Eduard Zingerman
2025-06-15 8:59 ` [RFC bpf-next 3/9] selftests/bpf: add selftests for new insn_set map Anton Protopopov
2025-06-18 11:04 ` Eduard Zingerman
2025-06-18 15:16 ` Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 4/9] bpf, x86: allow indirect jumps to r8...r15 Anton Protopopov
2025-06-17 19:41 ` Alexei Starovoitov
2025-06-18 14:28 ` Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 5/9] bpf, x86: add support for indirect jumps Anton Protopopov
2025-06-18 3:06 ` Alexei Starovoitov
2025-06-19 19:57 ` Anton Protopopov
2025-06-19 19:58 ` Anton Protopopov
2025-06-18 11:03 ` Eduard Zingerman
2025-06-19 20:13 ` Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 6/9] bpf: workaround llvm behaviour with " Anton Protopopov
2025-06-18 11:04 ` Eduard Zingerman
2025-06-18 13:59 ` Alexei Starovoitov
2025-06-15 8:59 ` [RFC bpf-next 7/9] bpf: disasm: add support for BPF_JMP|BPF_JA|BPF_X Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 8/9] libbpf: support llvm-generated indirect jumps Anton Protopopov
2025-06-18 3:22 ` Alexei Starovoitov
2025-06-18 15:08 ` Anton Protopopov
2025-07-07 23:45 ` Eduard Zingerman [this message]
2025-07-07 23:49 ` Alexei Starovoitov
2025-07-08 0:01 ` Eduard Zingerman
2025-07-08 0:12 ` Alexei Starovoitov
2025-07-08 0:18 ` Eduard Zingerman
2025-07-08 0:49 ` Alexei Starovoitov
2025-07-08 0:51 ` Eduard Zingerman
2025-07-08 20:59 ` Eduard Zingerman
2025-07-08 21:25 ` Alexei Starovoitov
2025-07-08 21:29 ` Eduard Zingerman
2025-07-09 5:33 ` Anton Protopopov
2025-07-09 5:58 ` Eduard Zingerman
2025-07-09 8:38 ` Eduard Zingerman
2025-07-10 5:11 ` Eduard Zingerman
2025-07-10 6:10 ` Anton Protopopov
2025-07-10 6:13 ` Eduard Zingerman
2025-06-18 19:49 ` Eduard Zingerman
2025-06-27 2:28 ` Eduard Zingerman
2025-06-27 10:18 ` Anton Protopopov
2025-07-03 18:21 ` Eduard Zingerman
2025-07-03 19:03 ` Anton Protopopov
2025-07-07 19:07 ` Eduard Zingerman
2025-07-07 19:34 ` Anton Protopopov
2025-07-07 21:44 ` Yonghong Song
2025-07-08 5:58 ` Yonghong Song
2025-07-08 8:30 ` Eduard Zingerman
2025-07-08 10:42 ` Eduard Zingerman
2025-06-15 8:59 ` [RFC bpf-next 9/9] selftests/bpf: add selftests for " Anton Protopopov
2025-06-18 3:24 ` Alexei Starovoitov
2025-06-18 14:49 ` Anton Protopopov
2025-06-18 16:01 ` Alexei Starovoitov
2025-06-18 16:36 ` Anton Protopopov
2025-06-18 16:43 ` Alexei Starovoitov
2025-06-18 20:25 ` Anton Protopopov
2025-06-18 21:59 ` Alexei Starovoitov
2025-06-19 5:05 ` Anton Protopopov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e726d778a3cf75e3ceec54f5f43b9d5d66ba5e97.camel@gmail.com \
--to=eddyz87@gmail.com \
--cc=a.s.protopopov@gmail.com \
--cc=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=aspsk@isovalent.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=qmo@kernel.org \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).