[PATCH v4 11/12] bpftool: Add support for signing BPF programs
KP Singh
kpsingh at kernel.org
Sun Sep 21 11:29:04 UTC 2025
On Sun, Sep 21, 2025 at 12:04 PM KP Singh <kpsingh at kernel.org> wrote:
>
> On Sun, Sep 21, 2025 at 12:00 PM KP Singh <kpsingh at kernel.org> wrote:
> >
> > On Thu, Sep 18, 2025 at 11:04 PM Quentin Monnet <qmo at kernel.org> wrote:
> > >
> > > 2025-09-14 23:51 UTC+0200 ~ KP Singh <kpsingh at kernel.org>
> > > > Two modes of operation being added:
> > > >
> > > > Add two modes of operation:
> > > >
> > > > * For prog load, allow signing a program immediately before loading. This
> > > > is essential for command-line testing and administration.
> > > >
> > > > bpftool prog load -S -k <private_key> -i <identity_cert> fentry_test.bpf.o
> > > >
> > > > * For gen skeleton, embed a pre-generated signature into the C skeleton
> > > > file. This supports the use of signed programs in compiled applications.
> > > >
> > > > bpftool gen skeleton -S -k <private_key> -i <identity_cert> fentry_test.bpf.o
> > > >
> > > > Generation of the loader program and its metadata map is implemented in
> > > > libbpf (bpf_obj__gen_loader). bpftool generates a skeleton that loads
> > > > the program and automates the required steps: freezing the map, creating
> > > > an exclusive map, loading, and running. Users can use standard libbpf
> > > > APIs directly or integrate loader program generation into their own
> > > > toolchains.
> > > >
> > > > Signed-off-by: KP Singh <kpsingh at kernel.org>
> > >
> > >
> > > Hi KP, thanks for this work! Apologies for the delay, I know I've missed
> > > v3 - and I still have some small nits from bpftool's side.
> > >
> > >
> > > > ---
> > > > .../bpf/bpftool/Documentation/bpftool-gen.rst | 16 +-
> > > > .../bpftool/Documentation/bpftool-prog.rst | 18 +-
> > > > tools/bpf/bpftool/Makefile | 6 +-
> > > > tools/bpf/bpftool/cgroup.c | 4 +
> > > > tools/bpf/bpftool/gen.c | 66 +++++-
> > > > tools/bpf/bpftool/main.c | 26 ++-
> > > > tools/bpf/bpftool/main.h | 11 +
> > > > tools/bpf/bpftool/prog.c | 27 ++-
> > > > tools/bpf/bpftool/sign.c | 212 ++++++++++++++++++
> > >
> > >
> > > We miss the bash completion update.
> >
> > I can send a separate follow up patch which we can review separately.
> > I don't want to block the series of bugs / comments in
> > bash-completion.
> >
> >
> > >
> > >
> > > > 9 files changed, 373 insertions(+), 13 deletions(-)
> > > > create mode 100644 tools/bpf/bpftool/sign.c
> > > >
> > > > diff --git a/tools/bpf/bpftool/Documentation/bpftool-gen.rst b/tools/bpf/bpftool/Documentation/bpftool-gen.rst
> > > > index ca860fd97d8d..cef469d758ed 100644
> > > > --- a/tools/bpf/bpftool/Documentation/bpftool-gen.rst
> > > > +++ b/tools/bpf/bpftool/Documentation/bpftool-gen.rst
> > > > @@ -16,7 +16,8 @@ SYNOPSIS
> > > >
> > > > **bpftool** [*OPTIONS*] **gen** *COMMAND*
> > > >
> > > > -*OPTIONS* := { |COMMON_OPTIONS| | { **-L** | **--use-loader** } }
> > > > +*OPTIONS* := { |COMMON_OPTIONS| [ { **-L** | **--use-loader** } ]
> > > > +[ { { **-S** | **--sign** } **-k** <private_key.pem> **-i** <certificate.x509> } ] }}
> > >
> > >
> > > Please don't remove the "|" separators. I understand we may use several
> > > of these options on the command line, but if we remove them this should
> > > be done consistently over all documentation pages.
> > >
> > >
> >
> > I had asked you in:
> >
> > https://lore.kernel.org/bpf/CACYkzJ42L-w_eXyc1k+E7yK4DGC3xjdiwjBAznYJdXWzuq4-jA@mail.gmail.com/
> >
> > about what you expect in the SYNOPSIS as the current formatting is not
> > correct for how the options are grouped but did not get a reply. It's
> > easier if you just mention in your reply what's expected.
> >
> > for now, I changed my bits and made a single group for signing in [ ]
> > but no | between these options. If this is not correct, let's follow
> > up as a separate patch and not block on merging this.
> >
> > - *OPTIONS* := { |COMMON_OPTIONS| | { **-L** | **--use-loader** } }
> > + *OPTIONS* := { |COMMON_OPTIONS| | { **-L** | **--use-loader** }
> > + | [ { **-S** | **--sign** } { **-k** <private_key.pem> } { **-i**
> > <certificate.x509> } ] }
> >
>
> Actually let's keep it consistent with what we print from the .c file:
>
> *OPTIONS* := { |COMMON_OPTIONS| |
> { **-f** | **--bpffs** } | { **-m** | **--mapcompat** } | { **-n** |
> **--nomount** } |
> { **-L** | **--use-loader** } | [ { **-S** | **--sign** } **-k**
> <private_key.pem> **-i** <certificate.x509> ] }
>
> and
>
> *OPTIONS* := { |COMMON_OPTIONS| | { **-L** | **--use-loader** }
> | [ { **-S** | **--sign** } **-k** <private_key.pem> **-i**
> <certificate.x509> ] }
>
> i.e a single group in [ ] without the | so that users know all these
> are required and no { } on short options as you mentioned for *.c
> lines.
>
> - KP
>
> >
> > > >
> > > > *COMMAND* := { **object** | **skeleton** | **help** }
> > > >
> > > > @@ -186,6 +187,19 @@ OPTIONS
> > > > skeleton). A light skeleton contains a loader eBPF program. It does not use
> > > > the majority of the libbpf infrastructure, and does not need libelf.
> > > >
> > > > +-S, --sign
> > > > + For skeletons, generate a signed skeleton. This option must be used with
> > > > + **-k** and **-i**. Using this flag implicitly enables **--use-loader**.
> > > > + See the "Signed Skeletons" section in the description of the
> > > > + **gen skeleton** command for more details.
> > >
> > >
> > > 404: Section not found!
> >
> > Removing this.
> >
> > >
> > >
> > > > +
> > > > +-k <private_key.pem>
> > > > + Path to the private key file in PEM format, required for signing.
> > > > +
> > > > +-i <certificate.x509>
> > > > + Path to the X.509 certificate file in PEM or DER format, required for
> > > > + signing.
> > > > +
> > > > EXAMPLES
> > > > ========
> > > > **$ cat example1.bpf.c**
> > > > diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
> > > > index f69fd92df8d8..55b812761df2 100644
> > > > --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst
> > > > +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
> > > > @@ -16,9 +16,9 @@ SYNOPSIS
> > > >
> > > > **bpftool** [*OPTIONS*] **prog** *COMMAND*
> > > >
> > > > -*OPTIONS* := { |COMMON_OPTIONS| |
> > > > -{ **-f** | **--bpffs** } | { **-m** | **--mapcompat** } | { **-n** | **--nomount** } |
> > > > -{ **-L** | **--use-loader** } }
> > > > +*OPTIONS* := { |COMMON_OPTIONS| [ { **-f** | **--bpffs** } ] [ { **-m** | **--mapcompat** } ]
> > > > +[ { **-n** | **--nomount** } ] [ { **-L** | **--use-loader** } ]
> > > > +[ { { **-S** | **--sign** } **-k** <private_key.pem> **-i** <certificate.x509> } ] }
> > >
> > >
> > > Same for "|" separators
> >
> > Done
> >
> > >
> > >
> > > >
> > > > *COMMANDS* :=
> > > > { **show** | **list** | **dump xlated** | **dump jited** | **pin** | **load** |
> > > > @@ -248,6 +248,18 @@ OPTIONS
> > > > creating the maps, and loading the programs (see **bpftool prog tracelog**
> > > > as a way to dump those messages).
> > > >
> > > > +-S, --sign
> > > > + Enable signing of the BPF program before loading. This option must be
> > > > + used with **-k** and **-i**. Using this flag implicitly enables
> > > > + **--use-loader**.
> > > > +
> > > > +-k <private_key.pem>
> > > > + Path to the private key file in PEM format, required when signing.
> > > > +
> > > > +-i <certificate.x509>
> > > > + Path to the X.509 certificate file in PEM or DER format, required when
> > > > + signing.
> > > > +
> > > > EXAMPLES
> > > > ========
> > > > **# bpftool prog show**
> > >
> > > > diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c
> > > > index 67a60114368f..694e61f1909e 100644
> > > > --- a/tools/bpf/bpftool/gen.c
> > > > +++ b/tools/bpf/bpftool/gen.c
> > >
> > > > @@ -1930,7 +1988,7 @@ static int do_help(int argc, char **argv)
> > > > " %1$s %2$s help\n"
> > > > "\n"
> > > > " " HELP_SPEC_OPTIONS " |\n"
> > > > - " {-L|--use-loader} }\n"
> > > > + " {-L|--use-loader} | [ {-S|--sign } {-k} <private_key.pem> {-i} <certificate.x509> ]}\n"
> > >
> > >
> > > Nit: No need for curly braces when you just have a short option name,
> > > for "-k" and "-i".
I now remember why I added curly braces here, without them the test fails:
kpsingh at kpsingh-genoa:~/projects/linux$ st
kpsingh at kpsingh-genoa:~/projects/linux/tools/testing/selftests/bpf$
./test_bpftool_synctypes.py
Comparing /home/kpsingh/projects/linux/tools/bpf/bpftool/prog.c
(do_help() OPTIONS) and
/home/kpsingh/projects/linux/tools/bpf/bpftool/Documentation/bpftool-prog.rst
(OPTIONS): {'-i', '-k'}
So, for now, I have put the curly braces so that the test passes.
More information about the Linux-security-module-archive
mailing list