blob: 1a9fd31aad6777adff6b0a1000d9c7cfa1c1b1a5 [file] [log] [blame]
Ken Chen45c7b152021-12-20 18:22:06 +08001/* Common BPF helpers to be used by all BPF programs loaded by Android */
2
3#include <linux/bpf.h>
4#include <stdbool.h>
5#include <stdint.h>
6
7#include "bpf_map_def.h"
8
9/******************************************************************************
Maciej Żenczykowski401c98f2024-08-15 14:55:05 -070010 * WARNING: CHANGES TO THIS FILE OUTSIDE OF AOSP/MAIN ARE LIKELY TO BREAK *
Ken Chen45c7b152021-12-20 18:22:06 +080011 * DEVICE COMPATIBILITY WITH MAINLINE MODULES SHIPPING EBPF CODE. *
12 * *
13 * THIS WILL LIKELY RESULT IN BRICKED DEVICES AT SOME ARBITRARY FUTURE TIME *
14 * *
15 * THAT GOES ESPECIALLY FOR THE 'SECTION' 'LICENSE' AND 'CRITICAL' MACROS *
16 * *
17 * We strongly suggest that if you need changes to bpfloader functionality *
18 * you get your changes reviewed and accepted into aosp/master. *
19 * *
20 ******************************************************************************/
21
Maciej Żenczykowski6f49c952022-05-24 16:07:16 -070022// The actual versions of the bpfloader that shipped in various Android releases
23
24// Android P/Q/R: BpfLoader was initially part of netd,
25// this was later split out into a standalone binary, but was unversioned.
26
27// Android S / 12 (api level 31) - added 'tethering' mainline eBPF support
28#define BPFLOADER_S_VERSION 2u
29
Maciej Żenczykowski1a542aa2022-06-22 19:07:15 -070030// Android T / 13 (api level 33) - support for shared/selinux_context/pindir
31#define BPFLOADER_T_VERSION 19u
32
Maciej Żenczykowskib6338ce2022-07-15 13:00:21 -070033// BpfLoader v0.25+ support obj@ver.o files
34#define BPFLOADER_OBJ_AT_VER_VERSION 25u
35
Ryan Zuklie888bd2d2023-01-04 16:09:02 -080036// Bpfloader v0.33+ supports {map,prog}.ignore_on_{eng,user,userdebug}
37#define BPFLOADER_IGNORED_ON_VERSION 33u
38
Maciej Żenczykowski1e697e52023-04-26 23:04:59 +000039// Android U / 14 (api level 34) - various new program types added
Maciej Żenczykowski11141da2024-03-15 18:21:33 -070040#define BPFLOADER_U_VERSION 38u
Maciej Żenczykowski1e697e52023-04-26 23:04:59 +000041
Maciej Żenczykowskibf6f9282024-06-13 13:08:10 -070042// Android U QPR2 / 14 (api level 34) - platform only
Maciej Żenczykowski0de80f12024-03-12 18:21:23 -070043// (note: the platform bpfloader in V isn't really versioned at all,
44// as there is no need as it can only load objects compiled at the
45// same time as itself and the rest of the platform)
Maciej Żenczykowskibf6f9282024-06-13 13:08:10 -070046#define BPFLOADER_U_QPR2_VERSION 41u
47#define BPFLOADER_PLATFORM_VERSION BPFLOADER_U_QPR2_VERSION
Maciej Żenczykowski0de80f12024-03-12 18:21:23 -070048
Maciej Żenczykowski65f70222024-03-18 14:43:09 -070049// Android Mainline - this bpfloader should eventually go back to T (or even S)
50// Note: this value (and the following +1u's) are hardcoded in NetBpfLoad.cpp
Maciej Żenczykowski84aa9ea2024-03-12 00:28:19 +000051#define BPFLOADER_MAINLINE_VERSION 42u
52
Maciej Żenczykowskide7374d2024-09-03 15:56:44 -070053// Android Mainline BpfLoader when running on Android T (sdk=33)
Maciej Żenczykowski65f70222024-03-18 14:43:09 -070054#define BPFLOADER_MAINLINE_T_VERSION (BPFLOADER_MAINLINE_VERSION + 1u)
55
Maciej Żenczykowskide7374d2024-09-03 15:56:44 -070056// Android Mainline BpfLoader when running on Android U (sdk=34)
Maciej Żenczykowski65f70222024-03-18 14:43:09 -070057#define BPFLOADER_MAINLINE_U_VERSION (BPFLOADER_MAINLINE_T_VERSION + 1u)
58
Maciej Żenczykowski1a3b54f2024-06-13 15:35:46 -070059// Android Mainline BpfLoader when running on Android U QPR3
60#define BPFLOADER_MAINLINE_U_QPR3_VERSION (BPFLOADER_MAINLINE_U_VERSION + 1u)
61
Maciej Żenczykowskide7374d2024-09-03 15:56:44 -070062// Android Mainline BpfLoader when running on Android V (sdk=35)
Maciej Żenczykowski1a3b54f2024-06-13 15:35:46 -070063#define BPFLOADER_MAINLINE_V_VERSION (BPFLOADER_MAINLINE_U_QPR3_VERSION + 1u)
Maciej Żenczykowski65f70222024-03-18 14:43:09 -070064
Maciej Żenczykowskide7374d2024-09-03 15:56:44 -070065// Android Mainline BpfLoader when running on Android W (sdk=36)
66#define BPFLOADER_MAINLINE_W_VERSION (BPFLOADER_MAINLINE_V_VERSION + 1u)
67
Ken Chen45c7b152021-12-20 18:22:06 +080068/* For mainline module use, you can #define BPFLOADER_{MIN/MAX}_VER
69 * before #include "bpf_helpers.h" to change which bpfloaders will
70 * process the resulting .o file.
71 *
72 * While this will work outside of mainline too, there just is no point to
73 * using it when the .o and the bpfloader ship in sync with each other.
Maciej Żenczykowski30a18082022-07-24 22:45:35 +000074 * In which case it's just best to use the default.
Ken Chen45c7b152021-12-20 18:22:06 +080075 */
76#ifndef BPFLOADER_MIN_VER
Maciej Żenczykowskifac81f12024-08-15 16:04:29 -070077#define BPFLOADER_MIN_VER BPFLOADER_PLATFORM_VERSION // inclusive, ie. >=
Ken Chen45c7b152021-12-20 18:22:06 +080078#endif
79
80#ifndef BPFLOADER_MAX_VER
Maciej Żenczykowskifac81f12024-08-15 16:04:29 -070081#define BPFLOADER_MAX_VER 0x10000u // exclusive, ie. < v1.0
Ken Chen45c7b152021-12-20 18:22:06 +080082#endif
83
84/* place things in different elf sections */
85#define SECTION(NAME) __attribute__((section(NAME), used))
86
87/* Must be present in every program, example usage:
88 * LICENSE("GPL"); or LICENSE("Apache 2.0");
89 *
90 * We also take this opportunity to embed a bunch of other useful values in
91 * the resulting .o (This is to enable some limited forward compatibility
92 * with mainline module shipped ebpf programs)
93 *
94 * The bpfloader_{min/max}_ver defines the [min, max) range of bpfloader
95 * versions that should load this .o file (bpfloaders outside of this range
96 * will simply ignore/skip this *entire* .o)
97 * The [inclusive,exclusive) matches what we do for kernel ver dependencies.
98 *
99 * The size_of_bpf_{map,prog}_def allow the bpfloader to load programs where
100 * these structures have been extended with additional fields (they will of
101 * course simply be ignored then).
102 *
103 * If missing, bpfloader_{min/max}_ver default to 0/0x10000 ie. [v0.0, v1.0),
104 * while size_of_bpf_{map/prog}_def default to 32/20 which are the v0.0 sizes.
Maciej Żenczykowski8837bf22023-06-09 05:50:30 +0000105 *
Maciej Żenczykowskida723a02024-08-16 18:44:33 -0700106 * This macro also disables loading BTF map debug information, as versions
107 * of the platform bpfloader that support BTF require fork-exec of btfloader
108 * which causes a regression in boot time.
Maciej Żenczykowski8837bf22023-06-09 05:50:30 +0000109 */
Maciej Żenczykowskida723a02024-08-16 18:44:33 -0700110#define LICENSE(NAME) \
111 unsigned int _bpfloader_min_ver SECTION("bpfloader_min_ver") = BPFLOADER_MIN_VER; \
112 unsigned int _bpfloader_max_ver SECTION("bpfloader_max_ver") = BPFLOADER_MAX_VER; \
113 size_t _size_of_bpf_map_def SECTION("size_of_bpf_map_def") = sizeof(struct bpf_map_def); \
114 size_t _size_of_bpf_prog_def SECTION("size_of_bpf_prog_def") = sizeof(struct bpf_prog_def); \
115 unsigned _btf_min_bpfloader_ver SECTION("btf_min_bpfloader_ver") = BPFLOADER_MAINLINE_VERSION; \
116 unsigned _btf_user_min_bpfloader_ver SECTION("btf_user_min_bpfloader_ver") = 0xFFFFFFFFu; \
117 char _license[] SECTION("license") = (NAME)
Maciej Żenczykowski8837bf22023-06-09 05:50:30 +0000118
Ken Chen45c7b152021-12-20 18:22:06 +0800119/* flag the resulting bpf .o file as critical to system functionality,
120 * loading all kernel version appropriate programs in it must succeed
121 * for bpfloader success
122 */
123#define CRITICAL(REASON) char _critical[] SECTION("critical") = (REASON)
124
125/*
126 * Helper functions called from eBPF programs written in C. These are
127 * implemented in the kernel sources.
128 */
129
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700130struct kver_uint { unsigned int kver; };
131#define KVER_(v) ((struct kver_uint){ .kver = (v) })
132#define KVER(a, b, c) KVER_(((a) << 24) + ((b) << 16) + (c))
133#define KVER_NONE KVER_(0)
134#define KVER_4_14 KVER(4, 14, 0)
135#define KVER_4_19 KVER(4, 19, 0)
Maciej Żenczykowski978b3f22024-03-10 22:11:28 +0000136#define KVER_5_4 KVER(5, 4, 0)
137#define KVER_5_8 KVER(5, 8, 0)
138#define KVER_5_9 KVER(5, 9, 0)
Maciej Żenczykowski22db5902024-05-10 06:44:08 -0700139#define KVER_5_10 KVER(5, 10, 0)
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700140#define KVER_5_15 KVER(5, 15, 0)
Maciej Żenczykowski978b3f22024-03-10 22:11:28 +0000141#define KVER_6_1 KVER(6, 1, 0)
142#define KVER_6_6 KVER(6, 6, 0)
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700143#define KVER_INF KVER_(0xFFFFFFFFu)
144
145#define KVER_IS_AT_LEAST(kver, a, b, c) ((kver).kver >= KVER(a, b, c).kver)
Ken Chen45c7b152021-12-20 18:22:06 +0800146
Patrick Rohr2f5c1152023-05-10 21:48:23 +0000147/*
148 * BPFFS (ie. /sys/fs/bpf) labelling is as follows:
149 * subdirectory selinux context mainline usecase / usable by
150 * / fs_bpf no [*] core operating system (ie. platform)
151 * /loader fs_bpf_loader no, U+ (as yet unused)
152 * /net_private fs_bpf_net_private yes, T+ network_stack
153 * /net_shared fs_bpf_net_shared yes, T+ network_stack & system_server
154 * /netd_readonly fs_bpf_netd_readonly yes, T+ network_stack & system_server & r/o to netd
155 * /netd_shared fs_bpf_netd_shared yes, T+ network_stack & system_server & netd [**]
156 * /tethering fs_bpf_tethering yes, S+ network_stack
157 * /vendor fs_bpf_vendor no, T+ vendor
158 *
159 * [*] initial support for bpf was added back in P,
160 * but things worked differently back then with no bpfloader,
161 * and instead netd doing stuff by hand,
162 * bpfloader with pinning into /sys/fs/bpf was (I believe) added in Q
163 * (and was definitely there in R).
164 *
165 * [**] additionally bpf programs are accessible to netutils_wrapper
166 * for use by iptables xt_bpf extensions.
167 *
168 * See cs/p:aosp-master%20-file:prebuilts/%20file:genfs_contexts%20"genfscon%20bpf"
169 */
170
Ken Chen45c7b152021-12-20 18:22:06 +0800171/* generic functions */
172
173/*
174 * Type-unsafe bpf map functions - avoid if possible.
175 *
176 * Using these it is possible to pass in keys/values of the wrong type/size,
177 * or, for 'bpf_map_lookup_elem_unsafe' receive into a pointer to the wrong type.
178 * You will not get a compile time failure, and for certain types of errors you
179 * might not even get a failure from the kernel's ebpf verifier during program load,
180 * instead stuff might just not work right at runtime.
181 *
182 * Instead please use:
183 * DEFINE_BPF_MAP(foo_map, TYPE, KeyType, ValueType, num_entries)
184 * where TYPE can be something like HASH or ARRAY, and num_entries is an integer.
185 *
186 * This defines the map (hence this should not be used in a header file included
187 * from multiple locations) and provides type safe accessors:
188 * ValueType * bpf_foo_map_lookup_elem(const KeyType *)
189 * int bpf_foo_map_update_elem(const KeyType *, const ValueType *, flags)
190 * int bpf_foo_map_delete_elem(const KeyType *)
191 *
192 * This will make sure that if you change the type of a map you'll get compile
193 * errors at any spots you forget to update with the new type.
194 *
195 * Note: these all take pointers to const map because from the C/eBPF point of view
196 * the map struct is really just a readonly map definition of the in kernel object.
197 * Runtime modification of the map defining struct is meaningless, since
198 * the contents is only ever used during bpf program loading & map creation
199 * by the bpf loader, and not by the eBPF program itself.
200 */
201static void* (*bpf_map_lookup_elem_unsafe)(const struct bpf_map_def* map,
202 const void* key) = (void*)BPF_FUNC_map_lookup_elem;
203static int (*bpf_map_update_elem_unsafe)(const struct bpf_map_def* map, const void* key,
204 const void* value, unsigned long long flags) = (void*)
205 BPF_FUNC_map_update_elem;
206static int (*bpf_map_delete_elem_unsafe)(const struct bpf_map_def* map,
207 const void* key) = (void*)BPF_FUNC_map_delete_elem;
Ryan Zuklie79ce8742022-11-21 17:19:25 -0800208static int (*bpf_ringbuf_output_unsafe)(const struct bpf_map_def* ringbuf,
209 const void* data, __u64 size, __u64 flags) = (void*)
210 BPF_FUNC_ringbuf_output;
211static void* (*bpf_ringbuf_reserve_unsafe)(const struct bpf_map_def* ringbuf,
212 __u64 size, __u64 flags) = (void*)
213 BPF_FUNC_ringbuf_reserve;
214static void (*bpf_ringbuf_submit_unsafe)(const void* data, __u64 flags) = (void*)
215 BPF_FUNC_ringbuf_submit;
Ken Chen45c7b152021-12-20 18:22:06 +0800216
Connor O'Brien56875452022-01-18 21:27:50 -0800217#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \
218 struct ____btf_map_##name { \
219 type_key key; \
220 type_val value; \
221 }; \
222 struct ____btf_map_##name \
223 __attribute__ ((section(".maps." #name), used)) \
224 ____btf_map_##name = { }
225
Maciej Żenczykowski6dec6e92023-10-06 14:52:46 -0700226#define BPF_ASSERT_LOADER_VERSION(min_loader, ignore_eng, ignore_user, ignore_userdebug) \
227 _Static_assert( \
228 (min_loader) >= BPFLOADER_IGNORED_ON_VERSION || \
229 !((ignore_eng).ignore_on_eng || \
230 (ignore_user).ignore_on_user || \
231 (ignore_userdebug).ignore_on_userdebug), \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800232 "bpfloader min version must be >= 0.33 in order to use ignored_on");
233
Ryan Zuklie79ce8742022-11-21 17:19:25 -0800234#define DEFINE_BPF_MAP_BASE(the_map, TYPE, keysize, valuesize, num_entries, \
235 usr, grp, md, selinux, pindir, share, minkver, \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800236 maxkver, minloader, maxloader, ignore_eng, \
237 ignore_user, ignore_userdebug) \
238 const struct bpf_map_def SECTION("maps") the_map = { \
239 .type = BPF_MAP_TYPE_##TYPE, \
240 .key_size = (keysize), \
241 .value_size = (valuesize), \
242 .max_entries = (num_entries), \
243 .map_flags = 0, \
244 .uid = (usr), \
245 .gid = (grp), \
246 .mode = (md), \
247 .bpfloader_min_ver = (minloader), \
248 .bpfloader_max_ver = (maxloader), \
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700249 .min_kver = (minkver).kver, \
250 .max_kver = (maxkver).kver, \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800251 .selinux_context = (selinux), \
252 .pin_subdir = (pindir), \
Maciej Żenczykowskia262bd32023-10-06 14:36:01 -0700253 .shared = (share).shared, \
Maciej Żenczykowski6dec6e92023-10-06 14:52:46 -0700254 .ignore_on_eng = (ignore_eng).ignore_on_eng, \
255 .ignore_on_user = (ignore_user).ignore_on_user, \
256 .ignore_on_userdebug = (ignore_userdebug).ignore_on_userdebug, \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800257 }; \
258 BPF_ASSERT_LOADER_VERSION(minloader, ignore_eng, ignore_user, ignore_userdebug);
Ryan Zuklie79ce8742022-11-21 17:19:25 -0800259
260// Type safe macro to declare a ring buffer and related output functions.
261// Compatibility:
262// * BPF ring buffers are only available kernels 5.8 and above. Any program
263// accessing the ring buffer should set a program level min_kver >= 5.8.
264// * The definition below sets a map min_kver of 5.8 which requires targeting
265// a BPFLOADER_MIN_VER >= BPFLOADER_S_VERSION.
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800266#define DEFINE_BPF_RINGBUF_EXT(the_map, ValueType, size_bytes, usr, grp, md, \
267 selinux, pindir, share, min_loader, max_loader, \
268 ignore_eng, ignore_user, ignore_userdebug) \
269 DEFINE_BPF_MAP_BASE(the_map, RINGBUF, 0, 0, size_bytes, usr, grp, md, \
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700270 selinux, pindir, share, KVER_5_8, KVER_INF, \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800271 min_loader, max_loader, ignore_eng, ignore_user, \
272 ignore_userdebug); \
Maciej Żenczykowskif1416b52023-06-16 16:30:46 +0000273 \
274 _Static_assert((size_bytes) >= 4096, "min 4 kiB ringbuffer size"); \
275 _Static_assert((size_bytes) <= 0x10000000, "max 256 MiB ringbuffer size"); \
276 _Static_assert(((size_bytes) & ((size_bytes) - 1)) == 0, \
277 "ring buffer size must be a power of two"); \
278 \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800279 static inline __always_inline __unused int bpf_##the_map##_output( \
280 const ValueType* v) { \
281 return bpf_ringbuf_output_unsafe(&the_map, v, sizeof(*v), 0); \
282 } \
Maciej Żenczykowskif1416b52023-06-16 16:30:46 +0000283 \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800284 static inline __always_inline __unused \
285 ValueType* bpf_##the_map##_reserve() { \
286 return bpf_ringbuf_reserve_unsafe(&the_map, sizeof(ValueType), 0); \
287 } \
Maciej Żenczykowskif1416b52023-06-16 16:30:46 +0000288 \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800289 static inline __always_inline __unused void bpf_##the_map##_submit( \
290 const ValueType* v) { \
291 bpf_ringbuf_submit_unsafe(v, 0); \
292 }
Ryan Zuklie79ce8742022-11-21 17:19:25 -0800293
Maciej Żenczykowski6f9830c2022-10-20 23:45:10 +0000294/* There exist buggy kernels with pre-T OS, that due to
295 * kernel patch "[ALPS05162612] bpf: fix ubsan error"
296 * do not support userspace writes into non-zero index of bpf map arrays.
297 *
298 * We use this assert to prevent us from being able to define such a map.
299 */
300
301#ifdef THIS_BPF_PROGRAM_IS_FOR_TEST_PURPOSES_ONLY
302#define BPF_MAP_ASSERT_OK(type, entries, mode)
Maciej Żenczykowski9ee26f72023-04-26 23:16:49 +0000303#elif BPFLOADER_MIN_VER >= BPFLOADER_T_VERSION
Maciej Żenczykowski6f9830c2022-10-20 23:45:10 +0000304#define BPF_MAP_ASSERT_OK(type, entries, mode)
305#else
306#define BPF_MAP_ASSERT_OK(type, entries, mode) \
307 _Static_assert(((type) != BPF_MAP_TYPE_ARRAY) || ((entries) <= 1) || !((mode) & 0222), \
308 "Writable arrays with more than 1 element not supported on pre-T devices.")
309#endif
310
Ken Chen45c7b152021-12-20 18:22:06 +0800311/* type safe macro to declare a map and related accessor functions */
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700312#define DEFINE_BPF_MAP_EXT(the_map, TYPE, KeyType, ValueType, num_entries, usr, grp, md, \
Ryan Zukliebe2ff672023-01-19 15:24:38 -0800313 selinux, pindir, share, min_loader, max_loader, ignore_eng, \
314 ignore_user, ignore_userdebug) \
Ryan Zuklie79ce8742022-11-21 17:19:25 -0800315 DEFINE_BPF_MAP_BASE(the_map, TYPE, sizeof(KeyType), sizeof(ValueType), \
316 num_entries, usr, grp, md, selinux, pindir, share, \
Ryan Zukliebe2ff672023-01-19 15:24:38 -0800317 KVER_NONE, KVER_INF, min_loader, max_loader, \
318 ignore_eng, ignore_user, ignore_userdebug); \
Maciej Żenczykowski6f9830c2022-10-20 23:45:10 +0000319 BPF_MAP_ASSERT_OK(BPF_MAP_TYPE_##TYPE, (num_entries), (md)); \
Maciej Żenczykowski5bec8b42023-06-07 06:59:20 +0000320 _Static_assert(sizeof(KeyType) < 1024, "aosp/2370288 requires < 1024 byte keys"); \
321 _Static_assert(sizeof(ValueType) < 65536, "aosp/2370288 requires < 65536 byte values"); \
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700322 BPF_ANNOTATE_KV_PAIR(the_map, KeyType, ValueType); \
Ken Chen45c7b152021-12-20 18:22:06 +0800323 \
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700324 static inline __always_inline __unused ValueType* bpf_##the_map##_lookup_elem( \
325 const KeyType* k) { \
Ken Chen45c7b152021-12-20 18:22:06 +0800326 return bpf_map_lookup_elem_unsafe(&the_map, k); \
327 }; \
328 \
329 static inline __always_inline __unused int bpf_##the_map##_update_elem( \
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700330 const KeyType* k, const ValueType* v, unsigned long long flags) { \
Ken Chen45c7b152021-12-20 18:22:06 +0800331 return bpf_map_update_elem_unsafe(&the_map, k, v, flags); \
332 }; \
333 \
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700334 static inline __always_inline __unused int bpf_##the_map##_delete_elem(const KeyType* k) { \
Ken Chen45c7b152021-12-20 18:22:06 +0800335 return bpf_map_delete_elem_unsafe(&the_map, k); \
336 };
337
Maciej Żenczykowski72e19c52022-07-08 14:22:57 -0700338#ifndef DEFAULT_BPF_MAP_SELINUX_CONTEXT
339#define DEFAULT_BPF_MAP_SELINUX_CONTEXT ""
340#endif
341
342#ifndef DEFAULT_BPF_MAP_PIN_SUBDIR
343#define DEFAULT_BPF_MAP_PIN_SUBDIR ""
344#endif
345
346#ifndef DEFAULT_BPF_MAP_UID
347#define DEFAULT_BPF_MAP_UID AID_ROOT
Maciej Żenczykowskieb4194e2022-07-21 13:33:16 +0000348#elif BPFLOADER_MIN_VER < 28u
349#error "Bpf Map UID must be left at default of AID_ROOT for BpfLoader prior to v0.28"
Maciej Żenczykowski72e19c52022-07-08 14:22:57 -0700350#endif
351
Maciej Żenczykowski10da6d42023-10-06 14:14:00 -0700352#define DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, usr, grp, md) \
353 DEFINE_BPF_MAP_EXT(the_map, TYPE, KeyType, ValueType, num_entries, usr, grp, md, \
354 DEFAULT_BPF_MAP_SELINUX_CONTEXT, DEFAULT_BPF_MAP_PIN_SUBDIR, PRIVATE, \
355 BPFLOADER_MIN_VER, BPFLOADER_MAX_VER, LOAD_ON_ENG, \
356 LOAD_ON_USER, LOAD_ON_USERDEBUG)
Ken Chen45c7b152021-12-20 18:22:06 +0800357
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700358#define DEFINE_BPF_MAP(the_map, TYPE, KeyType, ValueType, num_entries) \
Maciej Żenczykowski72e19c52022-07-08 14:22:57 -0700359 DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
360 DEFAULT_BPF_MAP_UID, AID_ROOT, 0600)
Ken Chen45c7b152021-12-20 18:22:06 +0800361
Maciej Żenczykowskidd3fe1d2022-10-20 04:05:00 +0000362#define DEFINE_BPF_MAP_RO(the_map, TYPE, KeyType, ValueType, num_entries, gid) \
363 DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
364 DEFAULT_BPF_MAP_UID, gid, 0440)
365
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700366#define DEFINE_BPF_MAP_GWO(the_map, TYPE, KeyType, ValueType, num_entries, gid) \
Maciej Żenczykowski72e19c52022-07-08 14:22:57 -0700367 DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
368 DEFAULT_BPF_MAP_UID, gid, 0620)
Ken Chen45c7b152021-12-20 18:22:06 +0800369
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700370#define DEFINE_BPF_MAP_GRO(the_map, TYPE, KeyType, ValueType, num_entries, gid) \
Maciej Żenczykowski72e19c52022-07-08 14:22:57 -0700371 DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
372 DEFAULT_BPF_MAP_UID, gid, 0640)
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700373
374#define DEFINE_BPF_MAP_GRW(the_map, TYPE, KeyType, ValueType, num_entries, gid) \
Maciej Żenczykowski72e19c52022-07-08 14:22:57 -0700375 DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
376 DEFAULT_BPF_MAP_UID, gid, 0660)
Ken Chen45c7b152021-12-20 18:22:06 +0800377
Maciej Żenczykowski31147002022-12-27 12:25:40 +0000378// LLVM eBPF builtins: they directly generate BPF_LD_ABS/BPF_LD_IND (skb may be ignored?)
379unsigned long long load_byte(void* skb, unsigned long long off) asm("llvm.bpf.load.byte");
380unsigned long long load_half(void* skb, unsigned long long off) asm("llvm.bpf.load.half");
381unsigned long long load_word(void* skb, unsigned long long off) asm("llvm.bpf.load.word");
382
Ken Chen45c7b152021-12-20 18:22:06 +0800383static int (*bpf_probe_read)(void* dst, int size, void* unsafe_ptr) = (void*) BPF_FUNC_probe_read;
384static int (*bpf_probe_read_str)(void* dst, int size, void* unsafe_ptr) = (void*) BPF_FUNC_probe_read_str;
Gopal Krishna Shukla26328882023-04-14 23:21:22 +0530385static int (*bpf_probe_read_user)(void* dst, int size, const void* unsafe_ptr) = (void*)BPF_FUNC_probe_read_user;
Steven Moreland59e34332023-03-29 00:12:36 +0000386static int (*bpf_probe_read_user_str)(void* dst, int size, const void* unsafe_ptr) = (void*) BPF_FUNC_probe_read_user_str;
Ken Chen45c7b152021-12-20 18:22:06 +0800387static unsigned long long (*bpf_ktime_get_ns)(void) = (void*) BPF_FUNC_ktime_get_ns;
388static unsigned long long (*bpf_ktime_get_boot_ns)(void) = (void*)BPF_FUNC_ktime_get_boot_ns;
Ken Chen45c7b152021-12-20 18:22:06 +0800389static unsigned long long (*bpf_get_current_pid_tgid)(void) = (void*) BPF_FUNC_get_current_pid_tgid;
390static unsigned long long (*bpf_get_current_uid_gid)(void) = (void*) BPF_FUNC_get_current_uid_gid;
391static unsigned long long (*bpf_get_smp_processor_id)(void) = (void*) BPF_FUNC_get_smp_processor_id;
eric.yanfa1baa12022-05-26 00:25:26 +0800392static long (*bpf_get_stackid)(void* ctx, void* map, uint64_t flags) = (void*) BPF_FUNC_get_stackid;
393static long (*bpf_get_current_comm)(void* buf, uint32_t buf_size) = (void*) BPF_FUNC_get_current_comm;
Ken Chen45c7b152021-12-20 18:22:06 +0800394
Maciej Żenczykowski3935d8b2024-09-03 19:19:04 -0700395// GPL only:
Maciej Żenczykowski2a8bf652024-08-29 11:57:08 -0700396static int (*bpf_trace_printk)(const char* fmt, int fmt_size, ...) = (void*) BPF_FUNC_trace_printk;
397#define bpf_printf(s, n...) bpf_trace_printk(s, sizeof(s), ## n)
398// Note: bpf only supports up to 3 arguments, log via: bpf_printf("msg %d %d %d", 1, 2, 3);
399// and read via the blocking: sudo cat /sys/kernel/debug/tracing/trace_pipe
400
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800401#define DEFINE_BPF_PROG_EXT(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
402 min_loader, max_loader, opt, selinux, pindir, ignore_eng, \
403 ignore_user, ignore_userdebug) \
404 const struct bpf_prog_def SECTION("progs") the_prog##_def = { \
405 .uid = (prog_uid), \
406 .gid = (prog_gid), \
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700407 .min_kver = (min_kv).kver, \
408 .max_kver = (max_kv).kver, \
Maciej Żenczykowskif2466ef2023-10-06 14:47:26 -0700409 .optional = (opt).optional, \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800410 .bpfloader_min_ver = (min_loader), \
411 .bpfloader_max_ver = (max_loader), \
412 .selinux_context = (selinux), \
413 .pin_subdir = (pindir), \
Maciej Żenczykowski6dec6e92023-10-06 14:52:46 -0700414 .ignore_on_eng = (ignore_eng).ignore_on_eng, \
415 .ignore_on_user = (ignore_user).ignore_on_user, \
416 .ignore_on_userdebug = (ignore_userdebug).ignore_on_userdebug, \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800417 }; \
418 SECTION(SECTION_NAME) \
Ken Chen45c7b152021-12-20 18:22:06 +0800419 int the_prog
420
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700421#define DEFINE_BPF_PROG_KVER_RANGE_OPT(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800422 opt) \
423 DEFINE_BPF_PROG_EXT(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
Maciej Żenczykowskif7abc432024-08-15 15:19:58 -0700424 BPFLOADER_MIN_VER, BPFLOADER_MAX_VER, opt, "", "", \
Maciej Żenczykowski10da6d42023-10-06 14:14:00 -0700425 LOAD_ON_ENG, LOAD_ON_USER, LOAD_ON_USERDEBUG)
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700426
Ken Chen45c7b152021-12-20 18:22:06 +0800427// Programs (here used in the sense of functions/sections) marked optional are allowed to fail
428// to load (for example due to missing kernel patches).
429// The bpfloader will just ignore these failures and continue processing the next section.
430//
431// A non-optional program (function/section) failing to load causes a failure and aborts
432// processing of the entire .o, if the .o is additionally marked critical, this will result
433// in the entire bpfloader process terminating with a failure and not setting the bpf.progs_loaded
434// system property. This in turn results in waitForProgsLoaded() never finishing.
435//
436// ie. a non-optional program in a critical .o is mandatory for kernels matching the min/max kver.
437
438// programs requiring a kernel version >= min_kv && < max_kv
439#define DEFINE_BPF_PROG_KVER_RANGE(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv) \
440 DEFINE_BPF_PROG_KVER_RANGE_OPT(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
Maciej Żenczykowski10da6d42023-10-06 14:14:00 -0700441 MANDATORY)
Ken Chen45c7b152021-12-20 18:22:06 +0800442#define DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, \
443 max_kv) \
Maciej Żenczykowski10da6d42023-10-06 14:14:00 -0700444 DEFINE_BPF_PROG_KVER_RANGE_OPT(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
445 OPTIONAL)
Ken Chen45c7b152021-12-20 18:22:06 +0800446
447// programs requiring a kernel version >= min_kv
448#define DEFINE_BPF_PROG_KVER(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv) \
449 DEFINE_BPF_PROG_KVER_RANGE_OPT(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, KVER_INF, \
Maciej Żenczykowski10da6d42023-10-06 14:14:00 -0700450 MANDATORY)
Ken Chen45c7b152021-12-20 18:22:06 +0800451#define DEFINE_OPTIONAL_BPF_PROG_KVER(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv) \
452 DEFINE_BPF_PROG_KVER_RANGE_OPT(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, KVER_INF, \
Maciej Żenczykowski10da6d42023-10-06 14:14:00 -0700453 OPTIONAL)
Ken Chen45c7b152021-12-20 18:22:06 +0800454
455// programs with no kernel version requirements
456#define DEFINE_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700457 DEFINE_BPF_PROG_KVER_RANGE_OPT(SECTION_NAME, prog_uid, prog_gid, the_prog, KVER_NONE, KVER_INF, \
Maciej Żenczykowski10da6d42023-10-06 14:14:00 -0700458 MANDATORY)
Ken Chen45c7b152021-12-20 18:22:06 +0800459#define DEFINE_OPTIONAL_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700460 DEFINE_BPF_PROG_KVER_RANGE_OPT(SECTION_NAME, prog_uid, prog_gid, the_prog, KVER_NONE, KVER_INF, \
Maciej Żenczykowski10da6d42023-10-06 14:14:00 -0700461 OPTIONAL)