From: Shung-Hsi Yu <shung-hsi.yu@suse.com>
To: Martin KaFai Lau <kafai@fb.com>
Cc: bpf@vger.kernel.org, Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
kernel-team@fb.com
Subject: Re: [PATCH bpf-next 2/3] bpf: selftests: Remove libcap usage from test_verifier
Date: Thu, 17 Mar 2022 15:04:37 +0800 [thread overview]
Message-ID: <YjLdhe9MK1hen9pk@syu-laptop.lan> (raw)
In-Reply-To: <YjKahUn7g6muDk2E@syu-laptop.lan>
On Thu, Mar 17, 2022 at 10:18:45AM +0800, Shung-Hsi Yu wrote:
> On Tue, Mar 15, 2022 at 06:48:54PM -0700, Martin KaFai Lau wrote:
> > This patch removes the libcap usage from test_verifier.
> > The cap_*_effective() helpers added in the earlier patch are
> > used instead.
> >
> > Signed-off-by: Martin KaFai Lau <kafai@fb.com>
> > ---
> > tools/testing/selftests/bpf/Makefile | 3 +-
> > tools/testing/selftests/bpf/test_verifier.c | 89 ++++++---------------
> > 2 files changed, 28 insertions(+), 64 deletions(-)
> >
> > diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
> > index fe12b4f5fe20..1c6e55740019 100644
> > --- a/tools/testing/selftests/bpf/Makefile
> > +++ b/tools/testing/selftests/bpf/Makefile
> > @@ -195,6 +195,7 @@ $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED): $(BPFOBJ)
> > CGROUP_HELPERS := $(OUTPUT)/cgroup_helpers.o
> > TESTING_HELPERS := $(OUTPUT)/testing_helpers.o
> > TRACE_HELPERS := $(OUTPUT)/trace_helpers.o
> > +CAP_HELPERS := $(OUTPUT)/cap_helpers.o
> >
> > $(OUTPUT)/test_dev_cgroup: $(CGROUP_HELPERS) $(TESTING_HELPERS)
> > $(OUTPUT)/test_skb_cgroup_id_user: $(CGROUP_HELPERS) $(TESTING_HELPERS)
> > @@ -211,7 +212,7 @@ $(OUTPUT)/test_lirc_mode2_user: $(TESTING_HELPERS)
> > $(OUTPUT)/xdping: $(TESTING_HELPERS)
> > $(OUTPUT)/flow_dissector_load: $(TESTING_HELPERS)
> > $(OUTPUT)/test_maps: $(TESTING_HELPERS)
> > -$(OUTPUT)/test_verifier: $(TESTING_HELPERS)
> > +$(OUTPUT)/test_verifier: $(TESTING_HELPERS) $(CAP_HELPERS)
> >
> > BPFTOOL ?= $(DEFAULT_BPFTOOL)
> > $(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \
> > diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
> > index 92e3465fbae8..091848662b7a 100644
> > --- a/tools/testing/selftests/bpf/test_verifier.c
> > +++ b/tools/testing/selftests/bpf/test_verifier.c
> > @@ -22,8 +22,7 @@
> > #include <limits.h>
> > #include <assert.h>
> >
> > -#include <sys/capability.h>
> > -
> > +#include <linux/capability.h>
> > #include <linux/unistd.h>
> > #include <linux/filter.h>
> > #include <linux/bpf_perf_event.h>
> > @@ -42,6 +41,7 @@
> > # define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1
> > # endif
> > #endif
> > +#include "cap_helpers.h"
> > #include "bpf_rand.h"
> > #include "bpf_util.h"
> > #include "test_btf.h"
> > @@ -62,6 +62,10 @@
> > #define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
> > #define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
> >
> > +/* need CAP_BPF, CAP_NET_ADMIN, CAP_PERFMON to load progs */
> > +#define ADMIN_CAPS (1ULL << CAP_NET_ADMIN | \
> > + 1ULL << CAP_PERFMON | \
> > + 1ULL << CAP_BPF)
> > #define UNPRIV_SYSCTL "kernel/unprivileged_bpf_disabled"
> > static bool unpriv_disabled = false;
> > static int skips;
> > @@ -973,47 +977,19 @@ struct libcap {
> >
> > static int set_admin(bool admin)
> > {
> > - cap_t caps;
> > - /* need CAP_BPF, CAP_NET_ADMIN, CAP_PERFMON to load progs */
> > - const cap_value_t cap_net_admin = CAP_NET_ADMIN;
> > - const cap_value_t cap_sys_admin = CAP_SYS_ADMIN;
> > - struct libcap *cap;
> > - int ret = -1;
> > -
> > - caps = cap_get_proc();
> > - if (!caps) {
> > - perror("cap_get_proc");
> > - return -1;
> > - }
> > - cap = (struct libcap *)caps;
> > - if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_sys_admin, CAP_CLEAR)) {
> > - perror("cap_set_flag clear admin");
> > - goto out;
> > - }
> > - if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_net_admin,
> > - admin ? CAP_SET : CAP_CLEAR)) {
> > - perror("cap_set_flag set_or_clear net");
> > - goto out;
> > - }
> > - /* libcap is likely old and simply ignores CAP_BPF and CAP_PERFMON,
> > - * so update effective bits manually
> > - */
> > + int err;
> > +
> > if (admin) {
> > - cap->data[1].effective |= 1 << (38 /* CAP_PERFMON */ - 32);
> > - cap->data[1].effective |= 1 << (39 /* CAP_BPF */ - 32);
> > + err = cap_enable_effective(ADMIN_CAPS, NULL);
> > + if (err)
> > + perror("cap_enable_effective(ADMIN_CAPS)");
> > } else {
> > - cap->data[1].effective &= ~(1 << (38 - 32));
> > - cap->data[1].effective &= ~(1 << (39 - 32));
> > - }
> > - if (cap_set_proc(caps)) {
> > - perror("cap_set_proc");
> > - goto out;
> > + err = cap_disable_effective(ADMIN_CAPS, NULL);
> > + if (err)
> > + perror("cap_disable_effective(ADMIN_CAPS)");
> > }
> > - ret = 0;
> > -out:
> > - if (cap_free(caps))
> > - perror("cap_free");
> > - return ret;
> > +
> > + return err;
> > }
> >
> > static int do_prog_test_run(int fd_prog, bool unpriv, uint32_t expected_val,
> > @@ -1291,31 +1267,18 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
> >
> > static bool is_admin(void)
> > {
> > - cap_flag_value_t net_priv = CAP_CLEAR;
> > - bool perfmon_priv = false;
> > - bool bpf_priv = false;
> > - struct libcap *cap;
> > - cap_t caps;
> > -
> > -#ifdef CAP_IS_SUPPORTED
> > - if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
> > - perror("cap_get_flag");
> > - return false;
> > - }
> > -#endif
> > - caps = cap_get_proc();
> > - if (!caps) {
> > - perror("cap_get_proc");
> > + __u64 caps;
> > +
> > + /* The test checks for finer cap as CAP_NET_ADMIN,
> > + * CAP_PERFMON, and CAP_BPF instead of CAP_SYS_ADMIN.
> > + * Thus, disable CAP_SYS_ADMIN at the beginning.
> > + */
> > + if (cap_disable_effective(1ULL << CAP_SYS_ADMIN, &caps)) {
> > + perror("cap_disable_effective(CAP_SYS_ADMIN)");
> > return false;
> > }
>
> Seems slightly strange for a is_* function to have the side effect of
> disabling capability, also, this change of behavior in is_admin() is not in
> the commit message.
>
> Maybe a better place to disable CAP_SYS_ADMIN is at the beginning of main()?
> That seems to be the only place is_admin() is called.
Just realized there's a v2 and it's already merged. Sorry for the noise.
Shung-Hsi
> > - cap = (struct libcap *)caps;
> > - bpf_priv = cap->data[1].effective & (1 << (39/* CAP_BPF */ - 32));
> > - perfmon_priv = cap->data[1].effective & (1 << (38/* CAP_PERFMON */ - 32));
> > - if (cap_get_flag(caps, CAP_NET_ADMIN, CAP_EFFECTIVE, &net_priv))
> > - perror("cap_get_flag NET");
> > - if (cap_free(caps))
> > - perror("cap_free");
> > - return bpf_priv && perfmon_priv && net_priv == CAP_SET;
> > +
> > + return (caps & ADMIN_CAPS) == ADMIN_CAPS;
> > }
> >
> > static void get_unpriv_disabled()
> > --
> > 2.30.2
> >
> >
next prev parent reply other threads:[~2022-03-17 7:04 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-16 1:48 [PATCH bpf-next 0/3] Remove libcap dependency from bpf selftests Martin KaFai Lau
2022-03-16 1:48 ` [PATCH bpf-next 1/3] bpf: selftests: Add helpers to directly use the capget and capset syscall Martin KaFai Lau
2022-03-16 6:17 ` John Fastabend
2022-03-16 1:48 ` [PATCH bpf-next 2/3] bpf: selftests: Remove libcap usage from test_verifier Martin KaFai Lau
2022-03-17 2:18 ` Shung-Hsi Yu
2022-03-17 7:04 ` Shung-Hsi Yu [this message]
2022-03-16 1:49 ` [PATCH bpf-next 3/3] bpf: selftests: Remove libcap usage from test_progs Martin KaFai Lau
2022-03-16 15:14 ` sdf
2022-03-16 5:36 ` [PATCH bpf-next 0/3] Remove libcap dependency from bpf selftests Andrii Nakryiko
2022-03-16 17:17 ` Martin KaFai Lau
2022-03-16 6:20 ` John Fastabend
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=YjLdhe9MK1hen9pk@syu-laptop.lan \
--to=shung-hsi.yu@suse.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=kafai@fb.com \
--cc=kernel-team@fb.com \
/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