From: Quentin Monnet <quentin@isovalent.com>
To: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>
Cc: bpf@vger.kernel.org, netdev@vger.kernel.org,
Quentin Monnet <quentin@isovalent.com>,
Richard Palethorpe <rpalethorpe@suse.com>,
Michael Kerrisk <mtk.manpages@gmail.com>
Subject: [PATCH bpf-next v3 3/3] tools: bpftool: make libcap dependency optional
Date: Wed, 29 Apr 2020 15:45:06 +0100 [thread overview]
Message-ID: <20200429144506.8999-4-quentin@isovalent.com> (raw)
In-Reply-To: <20200429144506.8999-1-quentin@isovalent.com>
The new libcap dependency is not used for an essential feature of
bpftool, and we could imagine building the tool without checks on
CAP_SYS_ADMIN by disabling probing features as an unprivileged users.
Make it so, in order to avoid a hard dependency on libcap, and to ease
packaging/embedding of bpftool.
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
---
.../bpftool/Documentation/bpftool-feature.rst | 4 ++-
tools/bpf/bpftool/Makefile | 13 +++++++---
tools/bpf/bpftool/feature.c | 26 +++++++++++++++++++
3 files changed, 38 insertions(+), 5 deletions(-)
diff --git a/tools/bpf/bpftool/Documentation/bpftool-feature.rst b/tools/bpf/bpftool/Documentation/bpftool-feature.rst
index ca085944e4cf..1fa755f55e0c 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-feature.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-feature.rst
@@ -55,7 +55,9 @@ DESCRIPTION
that case usually represent a small subset of the parameters
supported by the system. Unprivileged users MUST use the
**unprivileged** keyword: This is to avoid misdetection if
- bpftool is inadvertently run as non-root, for example.
+ bpftool is inadvertently run as non-root, for example. This
+ keyword is unavailable if bpftool was compiled without
+ libcap.
**bpftool feature probe dev** *NAME* [**full**] [**macros** [**prefix** *PREFIX*]]
Probe network device for supported eBPF features and dump
diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
index 89d7962a4a44..2759f9cc3289 100644
--- a/tools/bpf/bpftool/Makefile
+++ b/tools/bpf/bpftool/Makefile
@@ -55,16 +55,15 @@ ifneq ($(EXTRA_LDFLAGS),)
LDFLAGS += $(EXTRA_LDFLAGS)
endif
-LIBS = $(LIBBPF) -lelf -lz -lcap
-
INSTALL ?= install
RM ?= rm -f
CLANG ?= clang
FEATURE_USER = .bpftool
-FEATURE_TESTS = libbfd disassembler-four-args reallocarray zlib \
+FEATURE_TESTS = libbfd disassembler-four-args reallocarray zlib libcap \
+ clang-bpf-global-var
+FEATURE_DISPLAY = libbfd disassembler-four-args zlib libcap \
clang-bpf-global-var
-FEATURE_DISPLAY = libbfd disassembler-four-args zlib clang-bpf-global-var
check_feat := 1
NON_CHECK_FEAT_TARGETS := clean uninstall doc doc-clean doc-install doc-uninstall
@@ -90,6 +89,12 @@ ifeq ($(feature-reallocarray), 0)
CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
endif
+LIBS = $(LIBBPF) -lelf -lz
+ifeq ($(feature-libcap), 1)
+CFLAGS += -DUSE_LIBCAP
+LIBS += -lcap
+endif
+
include $(wildcard $(OUTPUT)*.d)
all: $(OUTPUT)bpftool
diff --git a/tools/bpf/bpftool/feature.c b/tools/bpf/bpftool/feature.c
index 952f4b1987c0..f54347f55ee0 100644
--- a/tools/bpf/bpftool/feature.c
+++ b/tools/bpf/bpftool/feature.c
@@ -6,7 +6,9 @@
#include <string.h>
#include <unistd.h>
#include <net/if.h>
+#ifdef USE_LIBCAP
#include <sys/capability.h>
+#endif
#include <sys/utsname.h>
#include <sys/vfs.h>
@@ -37,7 +39,9 @@ static const char * const helper_name[] = {
#undef BPF_HELPER_MAKE_ENTRY
static bool full_mode;
+#ifdef USE_LIBCAP
static bool run_as_unprivileged;
+#endif
/* Miscellaneous utility functions */
@@ -475,11 +479,13 @@ probe_prog_type(enum bpf_prog_type prog_type, bool *supported_types,
}
res = bpf_probe_prog_type(prog_type, ifindex);
+#ifdef USE_LIBCAP
/* Probe may succeed even if program load fails, for unprivileged users
* check that we did not fail because of insufficient permissions
*/
if (run_as_unprivileged && errno == EPERM)
res = false;
+#endif
supported_types[prog_type] |= res;
@@ -535,12 +541,14 @@ probe_helper_for_progtype(enum bpf_prog_type prog_type, bool supported_type,
if (supported_type) {
res = bpf_probe_helper(id, prog_type, ifindex);
+#ifdef USE_LIBCAP
/* Probe may succeed even if program load fails, for
* unprivileged users check that we did not fail because of
* insufficient permissions
*/
if (run_as_unprivileged && errno == EPERM)
res = false;
+#endif
}
if (json_output) {
@@ -738,6 +746,7 @@ static void section_misc(const char *define_prefix, __u32 ifindex)
static int handle_perms(void)
{
+#ifdef USE_LIBCAP
cap_value_t cap_list[1] = { CAP_SYS_ADMIN };
bool has_sys_admin_cap = false;
cap_flag_value_t val;
@@ -793,6 +802,18 @@ static int handle_perms(void)
}
return res;
+#else
+ /* Detection assumes user has sufficient privileges (CAP_SYS_ADMIN).
+ * We do not use libpcap so let's approximate, and restrict usage to
+ * root user only.
+ */
+ if (geteuid()) {
+ p_err("full feature probing requires root privileges");
+ return -1;
+ }
+
+ return 0;
+#endif /* USE_LIBCAP */
}
static int do_probe(int argc, char **argv)
@@ -852,8 +873,13 @@ static int do_probe(int argc, char **argv)
return -1;
define_prefix = GET_ARG();
} else if (is_prefix(*argv, "unprivileged")) {
+#ifdef USE_LIBCAP
run_as_unprivileged = true;
NEXT_ARG();
+#else
+ p_err("unprivileged run not supported, recompile bpftool with libcap");
+ return -1;
+#endif
} else {
p_err("expected no more arguments, 'kernel', 'dev', 'macros' or 'prefix', got: '%s'?",
*argv);
--
2.20.1
next prev parent reply other threads:[~2020-04-29 14:45 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-29 14:45 [PATCH bpf-next v3 0/3] tools: bpftool: probe features for unprivileged users Quentin Monnet
2020-04-29 14:45 ` [PATCH bpf-next v3 1/3] tools: bpftool: for "feature probe" define "full_mode" bool as global Quentin Monnet
2020-04-29 14:45 ` [PATCH bpf-next v3 2/3] tools: bpftool: allow unprivileged users to probe features Quentin Monnet
2020-04-29 14:45 ` Quentin Monnet [this message]
2020-04-29 20:10 ` [PATCH bpf-next v3 0/3] tools: bpftool: probe features for unprivileged users John Fastabend
2020-04-29 23:14 ` Daniel Borkmann
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=20200429144506.8999-4-quentin@isovalent.com \
--to=quentin@isovalent.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=mtk.manpages@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=rpalethorpe@suse.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