From: John Fastabend <john.fastabend@gmail.com>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>,
John Fastabend <john.fastabend@gmail.com>
Cc: Andrii Nakryiko <andrii@kernel.org>,
bpf@vger.kernel.org, netdev@vger.kernel.org,
paul@paul-moore.com, brauner@kernel.org,
linux-fsdevel@vger.kernel.org,
linux-security-module@vger.kernel.org, keescook@chromium.org,
kernel-team@meta.com, sargun@sargun.me
Subject: Re: [PATCH bpf-next 6/8] libbpf: wire up BPF token support at BPF object level
Date: Mon, 11 Dec 2023 16:26:54 -0800 [thread overview]
Message-ID: <6577a8ce777d9_1449c20858@john.notmuch> (raw)
In-Reply-To: <CAEf4BzYZ0Xkme8pwWoXE5wvQhp+DzUixn3ueJMFmDqUk9Dox7A@mail.gmail.com>
Andrii Nakryiko wrote:
> On Mon, Dec 11, 2023 at 2:56 PM John Fastabend <john.fastabend@gmail.com> wrote:
> >
> > Andrii Nakryiko wrote:
> > > Add BPF token support to BPF object-level functionality.
> > >
> > > BPF token is supported by BPF object logic either as an explicitly
> > > provided BPF token from outside (through BPF FS path or explicit BPF
> > > token FD), or implicitly (unless prevented through
> > > bpf_object_open_opts).
> > >
> > > Implicit mode is assumed to be the most common one for user namespaced
> > > unprivileged workloads. The assumption is that privileged container
> > > manager sets up default BPF FS mount point at /sys/fs/bpf with BPF token
> > > delegation options (delegate_{cmds,maps,progs,attachs} mount options).
> > > BPF object during loading will attempt to create BPF token from
> > > /sys/fs/bpf location, and pass it for all relevant operations
> > > (currently, map creation, BTF load, and program load).
> > >
> > > In this implicit mode, if BPF token creation fails due to whatever
> > > reason (BPF FS is not mounted, or kernel doesn't support BPF token,
> > > etc), this is not considered an error. BPF object loading sequence will
> > > proceed with no BPF token.
> > >
> > > In explicit BPF token mode, user provides explicitly either custom BPF
> > > FS mount point path or creates BPF token on their own and just passes
> > > token FD directly. In such case, BPF object will either dup() token FD
> > > (to not require caller to hold onto it for entire duration of BPF object
> > > lifetime) or will attempt to create BPF token from provided BPF FS
> > > location. If BPF token creation fails, that is considered a critical
> > > error and BPF object load fails with an error.
> > >
> > > Libbpf provides a way to disable implicit BPF token creation, if it
> > > causes any troubles (BPF token is designed to be completely optional and
> > > shouldn't cause any problems even if provided, but in the world of BPF
> > > LSM, custom security logic can be installed that might change outcome
> > > dependin on the presence of BPF token). To disable libbpf's default BPF
> > > token creation behavior user should provide either invalid BPF token FD
> > > (negative), or empty bpf_token_path option.
> > >
> > > BPF token presence can influence libbpf's feature probing, so if BPF
> > > object has associated BPF token, feature probing is instructed to use
> > > BPF object-specific feature detection cache and token FD.
> > >
> > > Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
> > > ---
> > > tools/lib/bpf/btf.c | 7 +-
> > > tools/lib/bpf/libbpf.c | 120 ++++++++++++++++++++++++++++++--
> > > tools/lib/bpf/libbpf.h | 28 +++++++-
> > > tools/lib/bpf/libbpf_internal.h | 17 ++++-
> > > 4 files changed, 160 insertions(+), 12 deletions(-)
> > >
> >
> > ...
> >
> > >
> > > +static int bpf_object_prepare_token(struct bpf_object *obj)
> > > +{
> > > + const char *bpffs_path;
> > > + int bpffs_fd = -1, token_fd, err;
> > > + bool mandatory;
> > > + enum libbpf_print_level level = LIBBPF_DEBUG;
> >
> > redundant set on level?
> >
>
> yep, removed initialization
>
> > > +
> > > + /* token is already set up */
> > > + if (obj->token_fd > 0)
> > > + return 0;
> > > + /* token is explicitly prevented */
> > > + if (obj->token_fd < 0) {
> > > + pr_debug("object '%s': token is prevented, skipping...\n", obj->name);
> > > + /* reset to zero to avoid extra checks during map_create and prog_load steps */
> > > + obj->token_fd = 0;
> > > + return 0;
> > > + }
> > > +
> > > + mandatory = obj->token_path != NULL;
> > > + level = mandatory ? LIBBPF_WARN : LIBBPF_DEBUG;
> > > +
> > > + bpffs_path = obj->token_path ?: BPF_FS_DEFAULT_PATH;
> > > + bpffs_fd = open(bpffs_path, O_DIRECTORY, O_RDWR);
> > > + if (bpffs_fd < 0) {
> > > + err = -errno;
> > > + __pr(level, "object '%s': failed (%d) to open BPF FS mount at '%s'%s\n",
> > > + obj->name, err, bpffs_path,
> > > + mandatory ? "" : ", skipping optional step...");
> > > + return mandatory ? err : 0;
> > > + }
> > > +
> > > + token_fd = bpf_token_create(bpffs_fd, 0);
> >
> > Did this get tested on older kernels? In that case TOKEN_CREATE will
> > fail with -EINVAL.
>
> yep, I did actually test, it will generate expected *debug*-level
> "failed to create BPF token" message
Great.
>
> >
> > > + close(bpffs_fd);
> > > + if (token_fd < 0) {
> > > + if (!mandatory && token_fd == -ENOENT) {
> > > + pr_debug("object '%s': BPF FS at '%s' doesn't have BPF token delegation set up, skipping...\n",
> > > + obj->name, bpffs_path);
> > > + return 0;
> > > + }
> >
> > Isn't there a case here we should give a warning about? If BPF_TOKEN_CREATE
> > exists and !mandatory, but default BPFFS failed for enomem, or eperm reasons?
> > If the user reall/y doesn't want tokens here they should maybe override with
> > -1 token? My thought is if you have delegations set up then something on the
> > system is trying to configure this and an error might be ok? I'm asking just
> > because I paused on it for a bit not sure either way at the moment. I might
> > imagine a lazy program not specifying the default bpffs, but also really
> > thinking its going to get a valid token.
>
> Interesting perspective! I actually came from the direction that BPF
> token is not really all that common and expected thing, and so in
> majority of cases (at least for some time) we won't be expecting to
> have BPF FS with delegation options. So emitting a warning that
> "something something BPF token failed" would be disconcerting to most
> users.
>
> What's the worst that would happen if BPF token was expected but we
> failed to instantiate it? You'll get a BPF object load failure with
> -EPERM, so it will be a pretty clear signal that whatever delegation
> was supposed to happen didn't happen.
>
> Also, if a user wants a BPF token for sure, they can explicitly set
> bpf_token_path = "/sys/fs/bpf" and then it becomes mandatory.
>
> So tl;dr, my perspective is that most users won't know or care about
> BPF tokens. If sysadmin set up BPF FS correctly, it should just work
> without the BPF application being aware. But for those rare cases
> where a BPF token is expected and necessary, explicit bpf_token_path
> or bpf_token_fd is the way to fail early, if something is not set up
> the way it is expected.
Works for me. I don't have a strong opinion either way.
next prev parent reply other threads:[~2023-12-12 0:26 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-07 18:54 [PATCH bpf-next 0/8] BPF token support in libbpf's BPF object Andrii Nakryiko
2023-12-07 18:54 ` [PATCH bpf-next 1/8] bpf: fail BPF_TOKEN_CREATE if no delegation option was set on BPF FS Andrii Nakryiko
2023-12-08 21:49 ` Christian Brauner
2023-12-08 22:42 ` Andrii Nakryiko
2023-12-11 21:33 ` John Fastabend
2023-12-07 18:54 ` [PATCH bpf-next 2/8] libbpf: split feature detectors definitions from cached results Andrii Nakryiko
2023-12-11 21:38 ` John Fastabend
2023-12-07 18:54 ` [PATCH bpf-next 3/8] libbpf: further decouple feature checking logic from bpf_object Andrii Nakryiko
2023-12-10 15:31 ` Eduard Zingerman
2023-12-11 18:20 ` Andrii Nakryiko
2023-12-11 21:41 ` John Fastabend
2023-12-11 22:50 ` Andrii Nakryiko
2023-12-07 18:54 ` [PATCH bpf-next 4/8] libbpf: move feature detection code into its own file Andrii Nakryiko
2023-12-11 21:41 ` John Fastabend
2023-12-07 18:54 ` [PATCH bpf-next 5/8] libbpf: wire up token_fd into feature probing logic Andrii Nakryiko
2023-12-11 21:44 ` John Fastabend
2023-12-07 18:54 ` [PATCH bpf-next 6/8] libbpf: wire up BPF token support at BPF object level Andrii Nakryiko
2023-12-11 22:56 ` John Fastabend
2023-12-12 0:05 ` Andrii Nakryiko
2023-12-12 0:26 ` John Fastabend [this message]
2023-12-07 18:54 ` [PATCH bpf-next 7/8] selftests/bpf: add BPF object loading tests with explicit token passing Andrii Nakryiko
2023-12-11 22:59 ` John Fastabend
2023-12-07 18:54 ` [PATCH bpf-next 8/8] selftests/bpf: add tests for BPF object load with implicit token Andrii Nakryiko
2023-12-11 23:00 ` John Fastabend
2023-12-10 15:30 ` [PATCH bpf-next 0/8] BPF token support in libbpf's BPF object Eduard Zingerman
2023-12-11 18:21 ` Andrii Nakryiko
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=6577a8ce777d9_1449c20858@john.notmuch \
--to=john.fastabend@gmail.com \
--cc=andrii.nakryiko@gmail.com \
--cc=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=brauner@kernel.org \
--cc=keescook@chromium.org \
--cc=kernel-team@meta.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=paul@paul-moore.com \
--cc=sargun@sargun.me \
/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).