From db324dfbca0d85fc5507bd6a147156dc77af3872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Thu, 11 Sep 2025 11:44:07 -0700 Subject: [PATCH] NetBpfLoad: eliminate 'bpfCmdFixupIsNeeded' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It turns out this doesn't work anyway: Both our Java and C++ higher level map opening logic on 4.14+ kernels will check key/value sizes match, which will fail due to the kernel uapi mismatch. (Note: that the fixup was only ever applied/enabled inside of the NetBpfLoad process itself, not in any later .so/Java/JNI) This removes the fixup and simply chooses to not even attempt to load bpf. This will result in the mainline bpf provided maps and programs simply not existing. This would/will cause a failure of 'bpf_existence_test' - but who cares, so long as things keep on booting. We need to transition to libbpf, and clearly making this work isn't worth the considerable effort it would be, since S ebpf functionality (ie. tethering offload) hasn't worked on the affected devices in years. Test: TreeHugger Flag: EXEMPT mainline Signed-off-by: Maciej Żenczykowski Change-Id: Ic93a5a9d5b3ba8078500e20dfdf00ef68256874c --- bpf/loader/NetBpfLoad.cpp | 12 +++++++----- bpf/syscall_wrappers/include/BpfSyscallWrappers.h | 14 ++------------ 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/bpf/loader/NetBpfLoad.cpp b/bpf/loader/NetBpfLoad.cpp index 3e6734f23d..e448f06b16 100644 --- a/bpf/loader/NetBpfLoad.cpp +++ b/bpf/loader/NetBpfLoad.cpp @@ -824,7 +824,7 @@ static int createMaps(ElfObject& elfObj, vector& md, vector< vector btfData; struct btf *btf = NULL; auto btfGuard = base::make_scope_guard([&btf] { if (btf) btf__free(btf); }); - if (isAtLeastKernelVersion(4, 19, 0) && !bpfCmdFixupIsNeeded) { + if (isAtLeastKernelVersion(4, 19, 0)) { // On Linux Kernels older than 4.18 BPF_BTF_LOAD command doesn't exist. ret = elfObj.readSectionByName(".BTF", btfData); if (ret) { @@ -1398,7 +1398,7 @@ static bool loadObject(const unsigned int bpfloader_ver, #define BPFROOT APEXROOT "/etc/bpf/mainline/" static bool loadAllObjects(const unsigned int bpfloader_ver) { - bool libbpf = !bpfCmdFixupIsNeeded && (isAtLeast25Q3 || USE_LIBBPF); + bool libbpf = isAtLeast25Q3 || USE_LIBBPF; if (!loadObject(bpfloader_ver, BPFROOT "offload.o")) return false; if (!loadObject(bpfloader_ver, BPFROOT "test.o", libbpf)) return false; if (isAtLeastT) { @@ -1885,8 +1885,10 @@ static int doLoad(char** argv, char * const envp[]) { if (next || errno != ENOENT) return 35; if (isAtLeastT || isAtLeastKernelVersion(4, 20, 0)) return 36; // implies Android S with 4.14 or 4.19 kernel - ALOGW("Enabling bpfCmdFixupIsNeeded."); - bpfCmdFixupIsNeeded = true; + ALOGW("Detected kernel with invalid BPF UAPI - disabling mainline use of eBPF."); + // leave a flag that we're 'done' + if (!createDir("/sys/fs/bpf/netd_shared/mainline_done")) return 43; // same as below + return 0; } } else { // implies S/T with 4.9 kernel // nothing we can do. @@ -1908,7 +1910,7 @@ static int doLoad(char** argv, char * const envp[]) { unique_fd map(createMap(BPF_MAP_TYPE_ARRAY, sizeof(int), sizeof(int), 2, 0)); int zero = 0; - int kernel_bugs = bpfCmdFixupIsNeeded; + int kernel_bugs = 0; if (writeToMapEntry(map, &zero, &kernel_bugs, BPF_ANY)) { ALOGE("Failure to write into index 0 of kernel bugs array."); return 38; diff --git a/bpf/syscall_wrappers/include/BpfSyscallWrappers.h b/bpf/syscall_wrappers/include/BpfSyscallWrappers.h index 8e021fc867..401c92bf5d 100644 --- a/bpf/syscall_wrappers/include/BpfSyscallWrappers.h +++ b/bpf/syscall_wrappers/include/BpfSyscallWrappers.h @@ -34,28 +34,18 @@ inline uint64_t ptr_to_u64(const void * const x) { return (uint64_t)(uintptr_t)x; } -#ifdef BPF_SUPPORT_CMD_FIXUP -static bool bpfCmdFixupIsNeeded = false; -#else -static constexpr bool bpfCmdFixupIsNeeded = false; -#endif - -inline long bpfCmdFixup(enum bpf_cmd cmd) { - return cmd + (cmd >= BPF_PROG_TEST_RUN && bpfCmdFixupIsNeeded); -} - /* Note: bpf_attr is a union which might have a much larger size then the anonymous struct portion * of it that we are using. The kernel's bpf() system call will perform a strict check to ensure * all unused portions are zero. It will fail with E2BIG if we don't fully zero bpf_attr. */ inline int bpf(enum bpf_cmd cmd, const bpf_attr& attr) { - return syscall(__NR_bpf, bpfCmdFixup(cmd), &attr, sizeof(attr)); + return syscall(__NR_bpf, cmd, &attr, sizeof(attr)); } // this version is meant for use with cmd's which mutate the argument inline int bpf(enum bpf_cmd cmd, bpf_attr *attr) { - return syscall(__NR_bpf, bpfCmdFixup(cmd), attr, sizeof(*attr)); + return syscall(__NR_bpf, cmd, attr, sizeof(*attr)); } inline int createMap(bpf_map_type map_type, uint32_t key_size, uint32_t value_size,