tools: bpftool: Make libcap dependency optional
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> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: John Fastabend <john.fastabend@gmail.com> Link: https://lore.kernel.org/bpf/20200429144506.8999-4-quentin@isovalent.com
This commit is contained in:
parent
cf9bf71452
commit
0b3b9ca3d1
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 @@ exit_free:
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue