From b3dba5438d238fb159fa26ecfad2be4f80d369e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Wed, 30 Jul 2025 18:12:35 -0700 Subject: [PATCH] bpf_map_def: introduce map name 'field' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The field is actually just a compile time calculate index into pin_location. We add a C++ only helper to return the ASCIIZ string at this offset. Temporary abort() added to show this is equivalent. Test: TreeHugger Flag: EXEMPT mainline/noop Signed-off-by: Maciej Żenczykowski Change-Id: If57390b99f348ab03b277e8f68e7f38636c751fc --- bpf/loader/NetBpfLoad.cpp | 2 ++ bpf/progs/include/bpf_helpers.h | 40 ++++++++++++++++----------------- bpf/progs/include/bpf_map_def.h | 16 ++++++++++++- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/bpf/loader/NetBpfLoad.cpp b/bpf/loader/NetBpfLoad.cpp index 9693007c53..dc131fc506 100644 --- a/bpf/loader/NetBpfLoad.cpp +++ b/bpf/loader/NetBpfLoad.cpp @@ -484,6 +484,8 @@ static bool mapMatchesExpectations(const unique_fd& fd, const string& mapName, // or a newly introduced kernel feature/bug (which is unlikely to get backported to 4.9). if (!isAtLeastKernelVersion(4, 14, 0)) return true; + if (strcmp(mapName.c_str(), mapDef.name())) abort(); + // Assuming fd is a valid Bpf Map file descriptor then // all the following should always succeed on a 4.14+ kernel. // If they somehow do fail, they'll return -1 (and set errno), diff --git a/bpf/progs/include/bpf_helpers.h b/bpf/progs/include/bpf_helpers.h index d252e314d7..a0c12d01fc 100644 --- a/bpf/progs/include/bpf_helpers.h +++ b/bpf/progs/include/bpf_helpers.h @@ -244,26 +244,26 @@ static int (*bpf_sk_storage_delete_unsafe) (const void* sk_storage, type == BPF_MAP_TYPE_SK_STORAGE) ? BPF_F_NO_PREALLOC : 0) \ ) -#define DEFINE_BPF_MAP_BASE(the_map, TYPE, keysize, valuesize, num_entries, \ - usr, grp, md, selinux, pindir, minkver, \ - maxkver, minloader, maxloader, mapflags) \ - VALIDATE_SELINUX_CONTEXT(minloader, selinux); \ - VALIDATE_PIN_DIR(minloader, pindir); \ - const struct bpf_map_def SECTION(".android_maps") the_map##_def = { \ - .type = BPF_MAP_TYPE_##TYPE, \ - .key_size = (keysize), \ - .value_size = (valuesize), \ - .max_entries = ABSOLUTE(num_entries), \ - .map_flags = DEFAULT_BPF_MAP_FLAGS(BPF_MAP_TYPE_##TYPE, num_entries, mapflags), \ - .uid = (usr), \ - .gid = (grp), \ - .mode = (md), \ - .bpfloader_min_ver = (minloader), \ - .bpfloader_max_ver = (maxloader), \ - .min_kver = (minkver).kver, \ - .max_kver = (maxkver).kver, \ - .create_location = CREATE_LOCATION(selinux), \ - .pin_location = "/sys/fs/bpf/" pindir "/map_" BPF_OBJ_NAME "_" #the_map, \ +#define DEFINE_BPF_MAP_BASE(the_map, TYPE, keysize, valuesize, num_entries, usr, grp, md, \ + selinux, pindir, minkver, maxkver, minloader, maxloader, mapflags) \ + VALIDATE_SELINUX_CONTEXT(minloader, selinux); \ + VALIDATE_PIN_DIR(minloader, pindir); \ + const struct bpf_map_def SECTION(".android_maps") the_map##_def = { \ + .type = BPF_MAP_TYPE_##TYPE, \ + .key_size = (keysize), \ + .value_size = (valuesize), \ + .max_entries = ABSOLUTE(num_entries), \ + .map_flags = DEFAULT_BPF_MAP_FLAGS(BPF_MAP_TYPE_##TYPE, num_entries, mapflags), \ + .uid = (usr), \ + .gid = (grp), \ + .mode = (md), \ + .bpfloader_min_ver = (minloader), \ + .bpfloader_max_ver = (maxloader), \ + .min_kver = (minkver).kver, \ + .max_kver = (maxkver).kver, \ + .create_location = CREATE_LOCATION(selinux), \ + .pin_location = "/sys/fs/bpf/" pindir "/map_" BPF_OBJ_NAME "_" #the_map, \ + .name_idx = __builtin_strlen("/sys/fs/bpf/" pindir "/map_" BPF_OBJ_NAME "_"), \ }; #define __uint(name, val) int (*name)[val] diff --git a/bpf/progs/include/bpf_map_def.h b/bpf/progs/include/bpf_map_def.h index 8e4a5def61..388d5ef265 100644 --- a/bpf/progs/include/bpf_map_def.h +++ b/bpf/progs/include/bpf_map_def.h @@ -25,6 +25,10 @@ // Pull in AID_* constants from //system/core/libcutils/include/private/android_filesystem_config.h #include +#ifdef __cplusplus +#include +#endif + /* * The bpf_{map,prog}_def structures are compiled for different architectures. * Once by the BPF compiler for the BPF architecture, and once by a C++ @@ -144,11 +148,21 @@ struct bpf_map_def { // These are fixed length ASCIIZ strings, padded with null bytes char create_location[BPF_DEF_CHAR_ARRAY_SIZE]; char pin_location[BPF_DEF_CHAR_ARRAY_SIZE]; + unsigned int name_idx; + +#ifdef __cplusplus + const char * name() const { return this->pin_location + this->name_idx; } +#endif }; +#ifdef __cplusplus +static_assert(std::is_pod_v); +static_assert(std::is_standard_layout_v); +#endif + // This needs to be updated whenever the above structure definition is expanded. // These asserts are here to make sure we have cross-6-arch consistency. -_Static_assert(sizeof(struct bpf_map_def) == 48 + 2 * BPF_DEF_CHAR_ARRAY_SIZE, "wrong sizeof struct bpf_map_def"); +_Static_assert(sizeof(struct bpf_map_def) == 52 + 2 * BPF_DEF_CHAR_ARRAY_SIZE, "wrong sizeof struct bpf_map_def"); _Static_assert(__alignof__(struct bpf_map_def) == 4, "__alignof__ struct bpf_map_def != 4"); _Static_assert(_Alignof(struct bpf_map_def) == 4, "_Alignof struct bpf_map_def != 4");