Skip to content

Commit 0b3b9ca

Browse files
qmonnetborkmann
authored andcommitted
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
1 parent cf9bf71 commit 0b3b9ca

File tree

3 files changed

+38
-5
lines changed

3 files changed

+38
-5
lines changed

tools/bpf/bpftool/Documentation/bpftool-feature.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ DESCRIPTION
5555
that case usually represent a small subset of the parameters
5656
supported by the system. Unprivileged users MUST use the
5757
**unprivileged** keyword: This is to avoid misdetection if
58-
bpftool is inadvertently run as non-root, for example.
58+
bpftool is inadvertently run as non-root, for example. This
59+
keyword is unavailable if bpftool was compiled without
60+
libcap.
5961

6062
**bpftool feature probe dev** *NAME* [**full**] [**macros** [**prefix** *PREFIX*]]
6163
Probe network device for supported eBPF features and dump

tools/bpf/bpftool/Makefile

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,15 @@ ifneq ($(EXTRA_LDFLAGS),)
5555
LDFLAGS += $(EXTRA_LDFLAGS)
5656
endif
5757

58-
LIBS = $(LIBBPF) -lelf -lz -lcap
59-
6058
INSTALL ?= install
6159
RM ?= rm -f
6260
CLANG ?= clang
6361

6462
FEATURE_USER = .bpftool
65-
FEATURE_TESTS = libbfd disassembler-four-args reallocarray zlib \
63+
FEATURE_TESTS = libbfd disassembler-four-args reallocarray zlib libcap \
64+
clang-bpf-global-var
65+
FEATURE_DISPLAY = libbfd disassembler-four-args zlib libcap \
6666
clang-bpf-global-var
67-
FEATURE_DISPLAY = libbfd disassembler-four-args zlib clang-bpf-global-var
6867

6968
check_feat := 1
7069
NON_CHECK_FEAT_TARGETS := clean uninstall doc doc-clean doc-install doc-uninstall
@@ -90,6 +89,12 @@ ifeq ($(feature-reallocarray), 0)
9089
CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
9190
endif
9291

92+
LIBS = $(LIBBPF) -lelf -lz
93+
ifeq ($(feature-libcap), 1)
94+
CFLAGS += -DUSE_LIBCAP
95+
LIBS += -lcap
96+
endif
97+
9398
include $(wildcard $(OUTPUT)*.d)
9499

95100
all: $(OUTPUT)bpftool

tools/bpf/bpftool/feature.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
#include <string.h>
77
#include <unistd.h>
88
#include <net/if.h>
9+
#ifdef USE_LIBCAP
910
#include <sys/capability.h>
11+
#endif
1012
#include <sys/utsname.h>
1113
#include <sys/vfs.h>
1214

@@ -37,7 +39,9 @@ static const char * const helper_name[] = {
3739
#undef BPF_HELPER_MAKE_ENTRY
3840

3941
static bool full_mode;
42+
#ifdef USE_LIBCAP
4043
static bool run_as_unprivileged;
44+
#endif
4145

4246
/* Miscellaneous utility functions */
4347

@@ -475,11 +479,13 @@ probe_prog_type(enum bpf_prog_type prog_type, bool *supported_types,
475479
}
476480

477481
res = bpf_probe_prog_type(prog_type, ifindex);
482+
#ifdef USE_LIBCAP
478483
/* Probe may succeed even if program load fails, for unprivileged users
479484
* check that we did not fail because of insufficient permissions
480485
*/
481486
if (run_as_unprivileged && errno == EPERM)
482487
res = false;
488+
#endif
483489

484490
supported_types[prog_type] |= res;
485491

@@ -535,12 +541,14 @@ probe_helper_for_progtype(enum bpf_prog_type prog_type, bool supported_type,
535541

536542
if (supported_type) {
537543
res = bpf_probe_helper(id, prog_type, ifindex);
544+
#ifdef USE_LIBCAP
538545
/* Probe may succeed even if program load fails, for
539546
* unprivileged users check that we did not fail because of
540547
* insufficient permissions
541548
*/
542549
if (run_as_unprivileged && errno == EPERM)
543550
res = false;
551+
#endif
544552
}
545553

546554
if (json_output) {
@@ -738,6 +746,7 @@ static void section_misc(const char *define_prefix, __u32 ifindex)
738746

739747
static int handle_perms(void)
740748
{
749+
#ifdef USE_LIBCAP
741750
cap_value_t cap_list[1] = { CAP_SYS_ADMIN };
742751
bool has_sys_admin_cap = false;
743752
cap_flag_value_t val;
@@ -793,6 +802,18 @@ static int handle_perms(void)
793802
}
794803

795804
return res;
805+
#else
806+
/* Detection assumes user has sufficient privileges (CAP_SYS_ADMIN).
807+
* We do not use libpcap so let's approximate, and restrict usage to
808+
* root user only.
809+
*/
810+
if (geteuid()) {
811+
p_err("full feature probing requires root privileges");
812+
return -1;
813+
}
814+
815+
return 0;
816+
#endif /* USE_LIBCAP */
796817
}
797818

798819
static int do_probe(int argc, char **argv)
@@ -852,8 +873,13 @@ static int do_probe(int argc, char **argv)
852873
return -1;
853874
define_prefix = GET_ARG();
854875
} else if (is_prefix(*argv, "unprivileged")) {
876+
#ifdef USE_LIBCAP
855877
run_as_unprivileged = true;
856878
NEXT_ARG();
879+
#else
880+
p_err("unprivileged run not supported, recompile bpftool with libcap");
881+
return -1;
882+
#endif
857883
} else {
858884
p_err("expected no more arguments, 'kernel', 'dev', 'macros' or 'prefix', got: '%s'?",
859885
*argv);

0 commit comments

Comments
 (0)