blob: c94f1d85caba02c810933442928847480e16fe34 [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 Żenczykowski65f70222024-03-18 14:43:09 -070053// Android Mainline BpfLoader when running on Android T
54#define BPFLOADER_MAINLINE_T_VERSION (BPFLOADER_MAINLINE_VERSION + 1u)
55
56// Android Mainline BpfLoader when running on Android U
57#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 Żenczykowski65f70222024-03-18 14:43:09 -070062// Android Mainline BpfLoader when running on Android V
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
Ken Chen45c7b152021-12-20 18:22:06 +080065/* For mainline module use, you can #define BPFLOADER_{MIN/MAX}_VER
66 * before #include "bpf_helpers.h" to change which bpfloaders will
67 * process the resulting .o file.
68 *
69 * While this will work outside of mainline too, there just is no point to
70 * using it when the .o and the bpfloader ship in sync with each other.
Maciej Żenczykowski30a18082022-07-24 22:45:35 +000071 * In which case it's just best to use the default.
Ken Chen45c7b152021-12-20 18:22:06 +080072 */
73#ifndef BPFLOADER_MIN_VER
Maciej Żenczykowskifac81f12024-08-15 16:04:29 -070074#define BPFLOADER_MIN_VER BPFLOADER_PLATFORM_VERSION // inclusive, ie. >=
Ken Chen45c7b152021-12-20 18:22:06 +080075#endif
76
77#ifndef BPFLOADER_MAX_VER
Maciej Żenczykowskifac81f12024-08-15 16:04:29 -070078#define BPFLOADER_MAX_VER 0x10000u // exclusive, ie. < v1.0
Ken Chen45c7b152021-12-20 18:22:06 +080079#endif
80
81/* place things in different elf sections */
82#define SECTION(NAME) __attribute__((section(NAME), used))
83
84/* Must be present in every program, example usage:
85 * LICENSE("GPL"); or LICENSE("Apache 2.0");
86 *
87 * We also take this opportunity to embed a bunch of other useful values in
88 * the resulting .o (This is to enable some limited forward compatibility
89 * with mainline module shipped ebpf programs)
90 *
91 * The bpfloader_{min/max}_ver defines the [min, max) range of bpfloader
92 * versions that should load this .o file (bpfloaders outside of this range
93 * will simply ignore/skip this *entire* .o)
94 * The [inclusive,exclusive) matches what we do for kernel ver dependencies.
95 *
96 * The size_of_bpf_{map,prog}_def allow the bpfloader to load programs where
97 * these structures have been extended with additional fields (they will of
98 * course simply be ignored then).
99 *
100 * If missing, bpfloader_{min/max}_ver default to 0/0x10000 ie. [v0.0, v1.0),
101 * while size_of_bpf_{map/prog}_def default to 32/20 which are the v0.0 sizes.
Maciej Żenczykowski8837bf22023-06-09 05:50:30 +0000102 *
Maciej Żenczykowskida723a02024-08-16 18:44:33 -0700103 * This macro also disables loading BTF map debug information, as versions
104 * of the platform bpfloader that support BTF require fork-exec of btfloader
105 * which causes a regression in boot time.
Maciej Żenczykowski8837bf22023-06-09 05:50:30 +0000106 */
Maciej Żenczykowskida723a02024-08-16 18:44:33 -0700107#define LICENSE(NAME) \
108 unsigned int _bpfloader_min_ver SECTION("bpfloader_min_ver") = BPFLOADER_MIN_VER; \
109 unsigned int _bpfloader_max_ver SECTION("bpfloader_max_ver") = BPFLOADER_MAX_VER; \
110 size_t _size_of_bpf_map_def SECTION("size_of_bpf_map_def") = sizeof(struct bpf_map_def); \
111 size_t _size_of_bpf_prog_def SECTION("size_of_bpf_prog_def") = sizeof(struct bpf_prog_def); \
112 unsigned _btf_min_bpfloader_ver SECTION("btf_min_bpfloader_ver") = BPFLOADER_MAINLINE_VERSION; \
113 unsigned _btf_user_min_bpfloader_ver SECTION("btf_user_min_bpfloader_ver") = 0xFFFFFFFFu; \
114 char _license[] SECTION("license") = (NAME)
Maciej Żenczykowski8837bf22023-06-09 05:50:30 +0000115
Ken Chen45c7b152021-12-20 18:22:06 +0800116/* flag the resulting bpf .o file as critical to system functionality,
117 * loading all kernel version appropriate programs in it must succeed
118 * for bpfloader success
119 */
120#define CRITICAL(REASON) char _critical[] SECTION("critical") = (REASON)
121
122/*
123 * Helper functions called from eBPF programs written in C. These are
124 * implemented in the kernel sources.
125 */
126
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700127struct kver_uint { unsigned int kver; };
128#define KVER_(v) ((struct kver_uint){ .kver = (v) })
129#define KVER(a, b, c) KVER_(((a) << 24) + ((b) << 16) + (c))
130#define KVER_NONE KVER_(0)
131#define KVER_4_14 KVER(4, 14, 0)
132#define KVER_4_19 KVER(4, 19, 0)
Maciej Żenczykowski978b3f22024-03-10 22:11:28 +0000133#define KVER_5_4 KVER(5, 4, 0)
134#define KVER_5_8 KVER(5, 8, 0)
135#define KVER_5_9 KVER(5, 9, 0)
Maciej Żenczykowski22db5902024-05-10 06:44:08 -0700136#define KVER_5_10 KVER(5, 10, 0)
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700137#define KVER_5_15 KVER(5, 15, 0)
Maciej Żenczykowski978b3f22024-03-10 22:11:28 +0000138#define KVER_6_1 KVER(6, 1, 0)
139#define KVER_6_6 KVER(6, 6, 0)
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700140#define KVER_INF KVER_(0xFFFFFFFFu)
141
142#define KVER_IS_AT_LEAST(kver, a, b, c) ((kver).kver >= KVER(a, b, c).kver)
Ken Chen45c7b152021-12-20 18:22:06 +0800143
Patrick Rohr2f5c1152023-05-10 21:48:23 +0000144/*
145 * BPFFS (ie. /sys/fs/bpf) labelling is as follows:
146 * subdirectory selinux context mainline usecase / usable by
147 * / fs_bpf no [*] core operating system (ie. platform)
148 * /loader fs_bpf_loader no, U+ (as yet unused)
149 * /net_private fs_bpf_net_private yes, T+ network_stack
150 * /net_shared fs_bpf_net_shared yes, T+ network_stack & system_server
151 * /netd_readonly fs_bpf_netd_readonly yes, T+ network_stack & system_server & r/o to netd
152 * /netd_shared fs_bpf_netd_shared yes, T+ network_stack & system_server & netd [**]
153 * /tethering fs_bpf_tethering yes, S+ network_stack
154 * /vendor fs_bpf_vendor no, T+ vendor
155 *
156 * [*] initial support for bpf was added back in P,
157 * but things worked differently back then with no bpfloader,
158 * and instead netd doing stuff by hand,
159 * bpfloader with pinning into /sys/fs/bpf was (I believe) added in Q
160 * (and was definitely there in R).
161 *
162 * [**] additionally bpf programs are accessible to netutils_wrapper
163 * for use by iptables xt_bpf extensions.
164 *
165 * See cs/p:aosp-master%20-file:prebuilts/%20file:genfs_contexts%20"genfscon%20bpf"
166 */
167
Ken Chen45c7b152021-12-20 18:22:06 +0800168/* generic functions */
169
170/*
171 * Type-unsafe bpf map functions - avoid if possible.
172 *
173 * Using these it is possible to pass in keys/values of the wrong type/size,
174 * or, for 'bpf_map_lookup_elem_unsafe' receive into a pointer to the wrong type.
175 * You will not get a compile time failure, and for certain types of errors you
176 * might not even get a failure from the kernel's ebpf verifier during program load,
177 * instead stuff might just not work right at runtime.
178 *
179 * Instead please use:
180 * DEFINE_BPF_MAP(foo_map, TYPE, KeyType, ValueType, num_entries)
181 * where TYPE can be something like HASH or ARRAY, and num_entries is an integer.
182 *
183 * This defines the map (hence this should not be used in a header file included
184 * from multiple locations) and provides type safe accessors:
185 * ValueType * bpf_foo_map_lookup_elem(const KeyType *)
186 * int bpf_foo_map_update_elem(const KeyType *, const ValueType *, flags)
187 * int bpf_foo_map_delete_elem(const KeyType *)
188 *
189 * This will make sure that if you change the type of a map you'll get compile
190 * errors at any spots you forget to update with the new type.
191 *
192 * Note: these all take pointers to const map because from the C/eBPF point of view
193 * the map struct is really just a readonly map definition of the in kernel object.
194 * Runtime modification of the map defining struct is meaningless, since
195 * the contents is only ever used during bpf program loading & map creation
196 * by the bpf loader, and not by the eBPF program itself.
197 */
198static void* (*bpf_map_lookup_elem_unsafe)(const struct bpf_map_def* map,
199 const void* key) = (void*)BPF_FUNC_map_lookup_elem;
200static int (*bpf_map_update_elem_unsafe)(const struct bpf_map_def* map, const void* key,
201 const void* value, unsigned long long flags) = (void*)
202 BPF_FUNC_map_update_elem;
203static int (*bpf_map_delete_elem_unsafe)(const struct bpf_map_def* map,
204 const void* key) = (void*)BPF_FUNC_map_delete_elem;
Ryan Zuklie79ce8742022-11-21 17:19:25 -0800205static int (*bpf_ringbuf_output_unsafe)(const struct bpf_map_def* ringbuf,
206 const void* data, __u64 size, __u64 flags) = (void*)
207 BPF_FUNC_ringbuf_output;
208static void* (*bpf_ringbuf_reserve_unsafe)(const struct bpf_map_def* ringbuf,
209 __u64 size, __u64 flags) = (void*)
210 BPF_FUNC_ringbuf_reserve;
211static void (*bpf_ringbuf_submit_unsafe)(const void* data, __u64 flags) = (void*)
212 BPF_FUNC_ringbuf_submit;
Ken Chen45c7b152021-12-20 18:22:06 +0800213
Connor O'Brien56875452022-01-18 21:27:50 -0800214#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \
215 struct ____btf_map_##name { \
216 type_key key; \
217 type_val value; \
218 }; \
219 struct ____btf_map_##name \
220 __attribute__ ((section(".maps." #name), used)) \
221 ____btf_map_##name = { }
222
Maciej Żenczykowski6dec6e92023-10-06 14:52:46 -0700223#define BPF_ASSERT_LOADER_VERSION(min_loader, ignore_eng, ignore_user, ignore_userdebug) \
224 _Static_assert( \
225 (min_loader) >= BPFLOADER_IGNORED_ON_VERSION || \
226 !((ignore_eng).ignore_on_eng || \
227 (ignore_user).ignore_on_user || \
228 (ignore_userdebug).ignore_on_userdebug), \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800229 "bpfloader min version must be >= 0.33 in order to use ignored_on");
230
Ryan Zuklie79ce8742022-11-21 17:19:25 -0800231#define DEFINE_BPF_MAP_BASE(the_map, TYPE, keysize, valuesize, num_entries, \
232 usr, grp, md, selinux, pindir, share, minkver, \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800233 maxkver, minloader, maxloader, ignore_eng, \
234 ignore_user, ignore_userdebug) \
235 const struct bpf_map_def SECTION("maps") the_map = { \
236 .type = BPF_MAP_TYPE_##TYPE, \
237 .key_size = (keysize), \
238 .value_size = (valuesize), \
239 .max_entries = (num_entries), \
240 .map_flags = 0, \
241 .uid = (usr), \
242 .gid = (grp), \
243 .mode = (md), \
244 .bpfloader_min_ver = (minloader), \
245 .bpfloader_max_ver = (maxloader), \
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700246 .min_kver = (minkver).kver, \
247 .max_kver = (maxkver).kver, \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800248 .selinux_context = (selinux), \
249 .pin_subdir = (pindir), \
Maciej Żenczykowskia262bd32023-10-06 14:36:01 -0700250 .shared = (share).shared, \
Maciej Żenczykowski6dec6e92023-10-06 14:52:46 -0700251 .ignore_on_eng = (ignore_eng).ignore_on_eng, \
252 .ignore_on_user = (ignore_user).ignore_on_user, \
253 .ignore_on_userdebug = (ignore_userdebug).ignore_on_userdebug, \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800254 }; \
255 BPF_ASSERT_LOADER_VERSION(minloader, ignore_eng, ignore_user, ignore_userdebug);
Ryan Zuklie79ce8742022-11-21 17:19:25 -0800256
257// Type safe macro to declare a ring buffer and related output functions.
258// Compatibility:
259// * BPF ring buffers are only available kernels 5.8 and above. Any program
260// accessing the ring buffer should set a program level min_kver >= 5.8.
261// * The definition below sets a map min_kver of 5.8 which requires targeting
262// a BPFLOADER_MIN_VER >= BPFLOADER_S_VERSION.
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800263#define DEFINE_BPF_RINGBUF_EXT(the_map, ValueType, size_bytes, usr, grp, md, \
264 selinux, pindir, share, min_loader, max_loader, \
265 ignore_eng, ignore_user, ignore_userdebug) \
266 DEFINE_BPF_MAP_BASE(the_map, RINGBUF, 0, 0, size_bytes, usr, grp, md, \
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700267 selinux, pindir, share, KVER_5_8, KVER_INF, \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800268 min_loader, max_loader, ignore_eng, ignore_user, \
269 ignore_userdebug); \
Maciej Żenczykowskif1416b52023-06-16 16:30:46 +0000270 \
271 _Static_assert((size_bytes) >= 4096, "min 4 kiB ringbuffer size"); \
272 _Static_assert((size_bytes) <= 0x10000000, "max 256 MiB ringbuffer size"); \
273 _Static_assert(((size_bytes) & ((size_bytes) - 1)) == 0, \
274 "ring buffer size must be a power of two"); \
275 \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800276 static inline __always_inline __unused int bpf_##the_map##_output( \
277 const ValueType* v) { \
278 return bpf_ringbuf_output_unsafe(&the_map, v, sizeof(*v), 0); \
279 } \
Maciej Żenczykowskif1416b52023-06-16 16:30:46 +0000280 \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800281 static inline __always_inline __unused \
282 ValueType* bpf_##the_map##_reserve() { \
283 return bpf_ringbuf_reserve_unsafe(&the_map, sizeof(ValueType), 0); \
284 } \
Maciej Żenczykowskif1416b52023-06-16 16:30:46 +0000285 \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800286 static inline __always_inline __unused void bpf_##the_map##_submit( \
287 const ValueType* v) { \
288 bpf_ringbuf_submit_unsafe(v, 0); \
289 }
Ryan Zuklie79ce8742022-11-21 17:19:25 -0800290
Maciej Żenczykowski6f9830c2022-10-20 23:45:10 +0000291/* There exist buggy kernels with pre-T OS, that due to
292 * kernel patch "[ALPS05162612] bpf: fix ubsan error"
293 * do not support userspace writes into non-zero index of bpf map arrays.
294 *
295 * We use this assert to prevent us from being able to define such a map.
296 */
297
298#ifdef THIS_BPF_PROGRAM_IS_FOR_TEST_PURPOSES_ONLY
299#define BPF_MAP_ASSERT_OK(type, entries, mode)
Maciej Żenczykowski9ee26f72023-04-26 23:16:49 +0000300#elif BPFLOADER_MIN_VER >= BPFLOADER_T_VERSION
Maciej Żenczykowski6f9830c2022-10-20 23:45:10 +0000301#define BPF_MAP_ASSERT_OK(type, entries, mode)
302#else
303#define BPF_MAP_ASSERT_OK(type, entries, mode) \
304 _Static_assert(((type) != BPF_MAP_TYPE_ARRAY) || ((entries) <= 1) || !((mode) & 0222), \
305 "Writable arrays with more than 1 element not supported on pre-T devices.")
306#endif
307
Ken Chen45c7b152021-12-20 18:22:06 +0800308/* type safe macro to declare a map and related accessor functions */
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700309#define DEFINE_BPF_MAP_EXT(the_map, TYPE, KeyType, ValueType, num_entries, usr, grp, md, \
Ryan Zukliebe2ff672023-01-19 15:24:38 -0800310 selinux, pindir, share, min_loader, max_loader, ignore_eng, \
311 ignore_user, ignore_userdebug) \
Ryan Zuklie79ce8742022-11-21 17:19:25 -0800312 DEFINE_BPF_MAP_BASE(the_map, TYPE, sizeof(KeyType), sizeof(ValueType), \
313 num_entries, usr, grp, md, selinux, pindir, share, \
Ryan Zukliebe2ff672023-01-19 15:24:38 -0800314 KVER_NONE, KVER_INF, min_loader, max_loader, \
315 ignore_eng, ignore_user, ignore_userdebug); \
Maciej Żenczykowski6f9830c2022-10-20 23:45:10 +0000316 BPF_MAP_ASSERT_OK(BPF_MAP_TYPE_##TYPE, (num_entries), (md)); \
Maciej Żenczykowski5bec8b42023-06-07 06:59:20 +0000317 _Static_assert(sizeof(KeyType) < 1024, "aosp/2370288 requires < 1024 byte keys"); \
318 _Static_assert(sizeof(ValueType) < 65536, "aosp/2370288 requires < 65536 byte values"); \
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700319 BPF_ANNOTATE_KV_PAIR(the_map, KeyType, ValueType); \
Ken Chen45c7b152021-12-20 18:22:06 +0800320 \
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700321 static inline __always_inline __unused ValueType* bpf_##the_map##_lookup_elem( \
322 const KeyType* k) { \
Ken Chen45c7b152021-12-20 18:22:06 +0800323 return bpf_map_lookup_elem_unsafe(&the_map, k); \
324 }; \
325 \
326 static inline __always_inline __unused int bpf_##the_map##_update_elem( \
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700327 const KeyType* k, const ValueType* v, unsigned long long flags) { \
Ken Chen45c7b152021-12-20 18:22:06 +0800328 return bpf_map_update_elem_unsafe(&the_map, k, v, flags); \
329 }; \
330 \
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700331 static inline __always_inline __unused int bpf_##the_map##_delete_elem(const KeyType* k) { \
Ken Chen45c7b152021-12-20 18:22:06 +0800332 return bpf_map_delete_elem_unsafe(&the_map, k); \
333 };
334
Maciej Żenczykowski72e19c52022-07-08 14:22:57 -0700335#ifndef DEFAULT_BPF_MAP_SELINUX_CONTEXT
336#define DEFAULT_BPF_MAP_SELINUX_CONTEXT ""
337#endif
338
339#ifndef DEFAULT_BPF_MAP_PIN_SUBDIR
340#define DEFAULT_BPF_MAP_PIN_SUBDIR ""
341#endif
342
343#ifndef DEFAULT_BPF_MAP_UID
344#define DEFAULT_BPF_MAP_UID AID_ROOT
Maciej Żenczykowskieb4194e2022-07-21 13:33:16 +0000345#elif BPFLOADER_MIN_VER < 28u
346#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 -0700347#endif
348
Maciej Żenczykowski10da6d42023-10-06 14:14:00 -0700349#define DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, usr, grp, md) \
350 DEFINE_BPF_MAP_EXT(the_map, TYPE, KeyType, ValueType, num_entries, usr, grp, md, \
351 DEFAULT_BPF_MAP_SELINUX_CONTEXT, DEFAULT_BPF_MAP_PIN_SUBDIR, PRIVATE, \
352 BPFLOADER_MIN_VER, BPFLOADER_MAX_VER, LOAD_ON_ENG, \
353 LOAD_ON_USER, LOAD_ON_USERDEBUG)
Ken Chen45c7b152021-12-20 18:22:06 +0800354
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700355#define DEFINE_BPF_MAP(the_map, TYPE, KeyType, ValueType, num_entries) \
Maciej Żenczykowski72e19c52022-07-08 14:22:57 -0700356 DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
357 DEFAULT_BPF_MAP_UID, AID_ROOT, 0600)
Ken Chen45c7b152021-12-20 18:22:06 +0800358
Maciej Żenczykowskidd3fe1d2022-10-20 04:05:00 +0000359#define DEFINE_BPF_MAP_RO(the_map, TYPE, KeyType, ValueType, num_entries, gid) \
360 DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
361 DEFAULT_BPF_MAP_UID, gid, 0440)
362
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700363#define DEFINE_BPF_MAP_GWO(the_map, TYPE, KeyType, ValueType, num_entries, gid) \
Maciej Żenczykowski72e19c52022-07-08 14:22:57 -0700364 DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
365 DEFAULT_BPF_MAP_UID, gid, 0620)
Ken Chen45c7b152021-12-20 18:22:06 +0800366
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700367#define DEFINE_BPF_MAP_GRO(the_map, TYPE, KeyType, ValueType, num_entries, gid) \
Maciej Żenczykowski72e19c52022-07-08 14:22:57 -0700368 DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
369 DEFAULT_BPF_MAP_UID, gid, 0640)
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700370
371#define DEFINE_BPF_MAP_GRW(the_map, TYPE, KeyType, ValueType, num_entries, gid) \
Maciej Żenczykowski72e19c52022-07-08 14:22:57 -0700372 DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
373 DEFAULT_BPF_MAP_UID, gid, 0660)
Ken Chen45c7b152021-12-20 18:22:06 +0800374
Maciej Żenczykowski31147002022-12-27 12:25:40 +0000375// LLVM eBPF builtins: they directly generate BPF_LD_ABS/BPF_LD_IND (skb may be ignored?)
376unsigned long long load_byte(void* skb, unsigned long long off) asm("llvm.bpf.load.byte");
377unsigned long long load_half(void* skb, unsigned long long off) asm("llvm.bpf.load.half");
378unsigned long long load_word(void* skb, unsigned long long off) asm("llvm.bpf.load.word");
379
Ken Chen45c7b152021-12-20 18:22:06 +0800380static int (*bpf_probe_read)(void* dst, int size, void* unsafe_ptr) = (void*) BPF_FUNC_probe_read;
381static 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 +0530382static 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 +0000383static 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 +0800384static unsigned long long (*bpf_ktime_get_ns)(void) = (void*) BPF_FUNC_ktime_get_ns;
385static unsigned long long (*bpf_ktime_get_boot_ns)(void) = (void*)BPF_FUNC_ktime_get_boot_ns;
386static int (*bpf_trace_printk)(const char* fmt, int fmt_size, ...) = (void*) BPF_FUNC_trace_printk;
387static unsigned long long (*bpf_get_current_pid_tgid)(void) = (void*) BPF_FUNC_get_current_pid_tgid;
388static unsigned long long (*bpf_get_current_uid_gid)(void) = (void*) BPF_FUNC_get_current_uid_gid;
389static unsigned long long (*bpf_get_smp_processor_id)(void) = (void*) BPF_FUNC_get_smp_processor_id;
eric.yanfa1baa12022-05-26 00:25:26 +0800390static long (*bpf_get_stackid)(void* ctx, void* map, uint64_t flags) = (void*) BPF_FUNC_get_stackid;
391static long (*bpf_get_current_comm)(void* buf, uint32_t buf_size) = (void*) BPF_FUNC_get_current_comm;
Ken Chen45c7b152021-12-20 18:22:06 +0800392
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800393#define DEFINE_BPF_PROG_EXT(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
394 min_loader, max_loader, opt, selinux, pindir, ignore_eng, \
395 ignore_user, ignore_userdebug) \
396 const struct bpf_prog_def SECTION("progs") the_prog##_def = { \
397 .uid = (prog_uid), \
398 .gid = (prog_gid), \
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700399 .min_kver = (min_kv).kver, \
400 .max_kver = (max_kv).kver, \
Maciej Żenczykowskif2466ef2023-10-06 14:47:26 -0700401 .optional = (opt).optional, \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800402 .bpfloader_min_ver = (min_loader), \
403 .bpfloader_max_ver = (max_loader), \
404 .selinux_context = (selinux), \
405 .pin_subdir = (pindir), \
Maciej Żenczykowski6dec6e92023-10-06 14:52:46 -0700406 .ignore_on_eng = (ignore_eng).ignore_on_eng, \
407 .ignore_on_user = (ignore_user).ignore_on_user, \
408 .ignore_on_userdebug = (ignore_userdebug).ignore_on_userdebug, \
Ryan Zuklie888bd2d2023-01-04 16:09:02 -0800409 }; \
410 SECTION(SECTION_NAME) \
Ken Chen45c7b152021-12-20 18:22:06 +0800411 int the_prog
412
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700413#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 -0800414 opt) \
415 DEFINE_BPF_PROG_EXT(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
Maciej Żenczykowskif7abc432024-08-15 15:19:58 -0700416 BPFLOADER_MIN_VER, BPFLOADER_MAX_VER, opt, "", "", \
Maciej Żenczykowski10da6d42023-10-06 14:14:00 -0700417 LOAD_ON_ENG, LOAD_ON_USER, LOAD_ON_USERDEBUG)
Maciej Żenczykowski53a144e2022-06-16 23:11:54 -0700418
Ken Chen45c7b152021-12-20 18:22:06 +0800419// Programs (here used in the sense of functions/sections) marked optional are allowed to fail
420// to load (for example due to missing kernel patches).
421// The bpfloader will just ignore these failures and continue processing the next section.
422//
423// A non-optional program (function/section) failing to load causes a failure and aborts
424// processing of the entire .o, if the .o is additionally marked critical, this will result
425// in the entire bpfloader process terminating with a failure and not setting the bpf.progs_loaded
426// system property. This in turn results in waitForProgsLoaded() never finishing.
427//
428// ie. a non-optional program in a critical .o is mandatory for kernels matching the min/max kver.
429
430// programs requiring a kernel version >= min_kv && < max_kv
431#define DEFINE_BPF_PROG_KVER_RANGE(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv) \
432 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 -0700433 MANDATORY)
Ken Chen45c7b152021-12-20 18:22:06 +0800434#define DEFINE_OPTIONAL_BPF_PROG_KVER_RANGE(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, \
435 max_kv) \
Maciej Żenczykowski10da6d42023-10-06 14:14:00 -0700436 DEFINE_BPF_PROG_KVER_RANGE_OPT(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
437 OPTIONAL)
Ken Chen45c7b152021-12-20 18:22:06 +0800438
439// programs requiring a kernel version >= min_kv
440#define DEFINE_BPF_PROG_KVER(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv) \
441 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 -0700442 MANDATORY)
Ken Chen45c7b152021-12-20 18:22:06 +0800443#define DEFINE_OPTIONAL_BPF_PROG_KVER(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv) \
444 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 -0700445 OPTIONAL)
Ken Chen45c7b152021-12-20 18:22:06 +0800446
447// programs with no kernel version requirements
448#define DEFINE_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700449 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 -0700450 MANDATORY)
Ken Chen45c7b152021-12-20 18:22:06 +0800451#define DEFINE_OPTIONAL_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
Maciej Żenczykowski3a645682023-10-06 15:11:01 -0700452 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 -0700453 OPTIONAL)