cc60b54340156ef3fdf97ffcd967c4b415380331
[openwrt/staging/stintel.git] /
1 From 847a6b7ee906be874f0cae279c8de902a7d3f092 Mon Sep 17 00:00:00 2001
2 From: Martin KaFai Lau <kafai@fb.com>
3 Date: Wed, 16 Mar 2022 10:38:29 -0700
4 Subject: [PATCH 2/3] bpf: selftests: Remove libcap usage from test_verifier
5
6 This patch removes the libcap usage from test_verifier.
7 The cap_*_effective() helpers added in the earlier patch are
8 used instead.
9
10 Signed-off-by: Martin KaFai Lau <kafai@fb.com>
11 Signed-off-by: Alexei Starovoitov <ast@kernel.org>
12 Acked-by: John Fastabend <john.fastabend@gmail.com>
13 Link: https://lore.kernel.org/bpf/20220316173829.2038682-1-kafai@fb.com
14 ---
15 tools/testing/selftests/bpf/Makefile | 31 +++++---
16 tools/testing/selftests/bpf/test_verifier.c | 88 ++++++---------------
17 2 files changed, 46 insertions(+), 73 deletions(-)
18
19 --- a/tools/testing/selftests/bpf/Makefile
20 +++ b/tools/testing/selftests/bpf/Makefile
21 @@ -189,16 +189,27 @@ TEST_GEN_PROGS_EXTENDED += $(DEFAULT_BPF
22
23 $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/test_stub.o $(BPFOBJ)
24
25 -$(OUTPUT)/test_dev_cgroup: cgroup_helpers.c
26 -$(OUTPUT)/test_skb_cgroup_id_user: cgroup_helpers.c
27 -$(OUTPUT)/test_sock: cgroup_helpers.c
28 -$(OUTPUT)/test_sock_addr: cgroup_helpers.c
29 -$(OUTPUT)/test_sockmap: cgroup_helpers.c
30 -$(OUTPUT)/test_tcpnotify_user: cgroup_helpers.c trace_helpers.c
31 -$(OUTPUT)/get_cgroup_id_user: cgroup_helpers.c
32 -$(OUTPUT)/test_cgroup_storage: cgroup_helpers.c
33 -$(OUTPUT)/test_sock_fields: cgroup_helpers.c
34 -$(OUTPUT)/test_sysctl: cgroup_helpers.c
35 +CGROUP_HELPERS := $(OUTPUT)/cgroup_helpers.o
36 +TESTING_HELPERS := $(OUTPUT)/testing_helpers.o
37 +TRACE_HELPERS := $(OUTPUT)/trace_helpers.o
38 +CAP_HELPERS := $(OUTPUT)/cap_helpers.o
39 +
40 +$(OUTPUT)/test_dev_cgroup: $(CGROUP_HELPERS) $(TESTING_HELPERS)
41 +$(OUTPUT)/test_skb_cgroup_id_user: $(CGROUP_HELPERS) $(TESTING_HELPERS)
42 +$(OUTPUT)/test_sock: $(CGROUP_HELPERS) $(TESTING_HELPERS)
43 +$(OUTPUT)/test_sock_addr: $(CGROUP_HELPERS) $(TESTING_HELPERS)
44 +$(OUTPUT)/test_sockmap: $(CGROUP_HELPERS) $(TESTING_HELPERS)
45 +$(OUTPUT)/test_tcpnotify_user: $(CGROUP_HELPERS) $(TESTING_HELPERS) $(TRACE_HELPERS)
46 +$(OUTPUT)/get_cgroup_id_user: $(CGROUP_HELPERS) $(TESTING_HELPERS)
47 +$(OUTPUT)/test_cgroup_storage: $(CGROUP_HELPERS) $(TESTING_HELPERS)
48 +$(OUTPUT)/test_sock_fields: $(CGROUP_HELPERS) $(TESTING_HELPERS)
49 +$(OUTPUT)/test_sysctl: $(CGROUP_HELPERS) $(TESTING_HELPERS)
50 +$(OUTPUT)/test_tag: $(TESTING_HELPERS)
51 +$(OUTPUT)/test_lirc_mode2_user: $(TESTING_HELPERS)
52 +$(OUTPUT)/xdping: $(TESTING_HELPERS)
53 +$(OUTPUT)/flow_dissector_load: $(TESTING_HELPERS)
54 +$(OUTPUT)/test_maps: $(TESTING_HELPERS)
55 +$(OUTPUT)/test_verifier: $(TESTING_HELPERS) $(CAP_HELPERS)
56
57 BPFTOOL ?= $(DEFAULT_BPFTOOL)
58 $(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \
59 --- a/tools/testing/selftests/bpf/test_verifier.c
60 +++ b/tools/testing/selftests/bpf/test_verifier.c
61 @@ -22,8 +22,6 @@
62 #include <limits.h>
63 #include <assert.h>
64
65 -#include <sys/capability.h>
66 -
67 #include <linux/unistd.h>
68 #include <linux/filter.h>
69 #include <linux/bpf_perf_event.h>
70 @@ -43,6 +41,7 @@
71 # endif
72 #endif
73 #include "bpf_rlimit.h"
74 +#include "cap_helpers.h"
75 #include "bpf_rand.h"
76 #include "bpf_util.h"
77 #include "test_btf.h"
78 @@ -59,6 +58,10 @@
79 #define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
80 #define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
81
82 +/* need CAP_BPF, CAP_NET_ADMIN, CAP_PERFMON to load progs */
83 +#define ADMIN_CAPS (1ULL << CAP_NET_ADMIN | \
84 + 1ULL << CAP_PERFMON | \
85 + 1ULL << CAP_BPF)
86 #define UNPRIV_SYSCTL "kernel/unprivileged_bpf_disabled"
87 static bool unpriv_disabled = false;
88 static int skips;
89 @@ -940,47 +943,19 @@ struct libcap {
90
91 static int set_admin(bool admin)
92 {
93 - cap_t caps;
94 - /* need CAP_BPF, CAP_NET_ADMIN, CAP_PERFMON to load progs */
95 - const cap_value_t cap_net_admin = CAP_NET_ADMIN;
96 - const cap_value_t cap_sys_admin = CAP_SYS_ADMIN;
97 - struct libcap *cap;
98 - int ret = -1;
99 -
100 - caps = cap_get_proc();
101 - if (!caps) {
102 - perror("cap_get_proc");
103 - return -1;
104 - }
105 - cap = (struct libcap *)caps;
106 - if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_sys_admin, CAP_CLEAR)) {
107 - perror("cap_set_flag clear admin");
108 - goto out;
109 - }
110 - if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_net_admin,
111 - admin ? CAP_SET : CAP_CLEAR)) {
112 - perror("cap_set_flag set_or_clear net");
113 - goto out;
114 - }
115 - /* libcap is likely old and simply ignores CAP_BPF and CAP_PERFMON,
116 - * so update effective bits manually
117 - */
118 + int err;
119 +
120 if (admin) {
121 - cap->data[1].effective |= 1 << (38 /* CAP_PERFMON */ - 32);
122 - cap->data[1].effective |= 1 << (39 /* CAP_BPF */ - 32);
123 + err = cap_enable_effective(ADMIN_CAPS, NULL);
124 + if (err)
125 + perror("cap_enable_effective(ADMIN_CAPS)");
126 } else {
127 - cap->data[1].effective &= ~(1 << (38 - 32));
128 - cap->data[1].effective &= ~(1 << (39 - 32));
129 + err = cap_disable_effective(ADMIN_CAPS, NULL);
130 + if (err)
131 + perror("cap_disable_effective(ADMIN_CAPS)");
132 }
133 - if (cap_set_proc(caps)) {
134 - perror("cap_set_proc");
135 - goto out;
136 - }
137 - ret = 0;
138 -out:
139 - if (cap_free(caps))
140 - perror("cap_free");
141 - return ret;
142 +
143 + return err;
144 }
145
146 static int do_prog_test_run(int fd_prog, bool unpriv, uint32_t expected_val,
147 @@ -1246,31 +1221,18 @@ fail_log:
148
149 static bool is_admin(void)
150 {
151 - cap_flag_value_t net_priv = CAP_CLEAR;
152 - bool perfmon_priv = false;
153 - bool bpf_priv = false;
154 - struct libcap *cap;
155 - cap_t caps;
156 -
157 -#ifdef CAP_IS_SUPPORTED
158 - if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
159 - perror("cap_get_flag");
160 - return false;
161 - }
162 -#endif
163 - caps = cap_get_proc();
164 - if (!caps) {
165 - perror("cap_get_proc");
166 + __u64 caps;
167 +
168 + /* The test checks for finer cap as CAP_NET_ADMIN,
169 + * CAP_PERFMON, and CAP_BPF instead of CAP_SYS_ADMIN.
170 + * Thus, disable CAP_SYS_ADMIN at the beginning.
171 + */
172 + if (cap_disable_effective(1ULL << CAP_SYS_ADMIN, &caps)) {
173 + perror("cap_disable_effective(CAP_SYS_ADMIN)");
174 return false;
175 }
176 - cap = (struct libcap *)caps;
177 - bpf_priv = cap->data[1].effective & (1 << (39/* CAP_BPF */ - 32));
178 - perfmon_priv = cap->data[1].effective & (1 << (38/* CAP_PERFMON */ - 32));
179 - if (cap_get_flag(caps, CAP_NET_ADMIN, CAP_EFFECTIVE, &net_priv))
180 - perror("cap_get_flag NET");
181 - if (cap_free(caps))
182 - perror("cap_free");
183 - return bpf_priv && perfmon_priv && net_priv == CAP_SET;
184 +
185 + return (caps & ADMIN_CAPS) == ADMIN_CAPS;
186 }
187
188 static void get_unpriv_disabled()