From 732386394e4c12a1df88367ca6161a5f10459a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Mon, 24 Feb 2025 14:50:09 -0800 Subject: [PATCH] bpf: move isAtLeastX to BpfUtils.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Partially due to: https://android-review.googlesource.com/c/platform/bionic/+/3497280 Test: TreeHugger Signed-off-by: Maciej Żenczykowski Change-Id: I74a626c45d641e226d7f71e00d0b542c5701417d --- bpf/headers/include/bpf/BpfUtils.h | 11 ++++++++++ bpf/loader/NetBpfLoad.cpp | 33 +--------------------------- bpf/netd/BpfHandler.cpp | 33 ++++++++++++---------------- bpf/tests/mts/bpf_existence_test.cpp | 16 +++++--------- tests/unit/jni/Android.bp | 1 + 5 files changed, 33 insertions(+), 61 deletions(-) diff --git a/bpf/headers/include/bpf/BpfUtils.h b/bpf/headers/include/bpf/BpfUtils.h index 9e8b2c74ee..ed08e1afe0 100644 --- a/bpf/headers/include/bpf/BpfUtils.h +++ b/bpf/headers/include/bpf/BpfUtils.h @@ -26,6 +26,7 @@ #include #include +#include #include #include "KernelUtils.h" @@ -33,6 +34,16 @@ namespace android { namespace bpf { +const bool unreleased = (base::GetProperty("ro.build.version.codename", "REL") != "REL"); +const int api_level = unreleased ? 10000 : android_get_device_api_level(); +const bool isAtLeastR = (api_level >= 30); +const bool isAtLeastS = (api_level >= 31); +// Sv2 is 32 +const bool isAtLeastT = (api_level >= 33); +const bool isAtLeastU = (api_level >= 34); +const bool isAtLeastV = (api_level >= 35); +const bool isAtLeast25Q2 = (api_level >= 36); + // See kernel's net/core/sock_diag.c __sock_gen_cookie() // the implementation of which guarantees 0 will never be returned, // primarily because 0 is used to mean not yet initialized, diff --git a/bpf/loader/NetBpfLoad.cpp b/bpf/loader/NetBpfLoad.cpp index 40d1281f26..9486e75d40 100644 --- a/bpf/loader/NetBpfLoad.cpp +++ b/bpf/loader/NetBpfLoad.cpp @@ -1414,37 +1414,6 @@ static bool isWear() { static int doLoad(char** argv, char * const envp[]) { const bool runningAsRoot = !getuid(); // true iff U QPR3 or V+ - // Any released device will have codename REL instead of a 'real' codename. - // For safety: default to 'REL' so we default to unreleased=false on failure. - const bool unreleased = (GetProperty("ro.build.version.codename", "REL") != "REL"); - - // goog/main device_api_level is bumped *way* before aosp/main api level - // (the latter only gets bumped during the push of goog/main to aosp/main) - // - // Since we develop in AOSP, we want it to behave as if it was bumped too. - // - // Note that AOSP doesn't really have a good api level (for example during - // early V dev cycle, it would have *all* of T, some but not all of U, and some V). - // One could argue that for our purposes AOSP api level should be infinite or 10000. - // - // This could also cause api to be increased in goog/main or other branches, - // but I can't imagine a case where this would be a problem: the problem - // is rather a too low api level, rather than some ill defined high value. - // For example as I write this aosp is 34/U, and goog is 35/V, - // we want to treat both goog & aosp as 35/V, but it's harmless if we - // treat goog as 36 because that value isn't yet defined to mean anything, - // and we thus never compare against it. - // - // Also note that 'android_get_device_api_level()' is what the - // //system/core/init/apex_init_util.cpp - // apex init .XXrc parsing code uses for XX filtering, and that code - // (now) similarly uses __ANDROID_API_FUTURE__ for non 'REL' codenames. - const int api_level = unreleased ? __ANDROID_API_FUTURE__ : android_get_device_api_level(); - const bool isAtLeastT = (api_level >= __ANDROID_API_T__); - const bool isAtLeastU = (api_level >= __ANDROID_API_U__); - const bool isAtLeastV = (api_level >= __ANDROID_API_V__); - const bool isAtLeast25Q2 = (api_level > __ANDROID_API_V__); // TODO: fix > - const int first_api_level = GetIntProperty("ro.board.first_api_level", api_level); // last in U QPR2 beta1 @@ -1591,7 +1560,7 @@ static int doLoad(char** argv, char * const envp[]) { if (isArm() && (isTV() || isWear())) { // exempt Arm TV or Wear devices (arm32 ABI is far less problematic than x86-32) ALOGW("[Arm TV/Wear] 32-bit userspace unsupported on 6.2+ kernels."); - } else if (first_api_level <= __ANDROID_API_T__ && isArm()) { + } else if (first_api_level <= 33 /*T*/ && isArm()) { // also exempt Arm devices upgrading with major kernel rev from T- // might possibly be better for them to run with a newer kernel... ALOGW("[Arm KernelUpRev] 32-bit userspace unsupported on 6.2+ kernels."); diff --git a/bpf/netd/BpfHandler.cpp b/bpf/netd/BpfHandler.cpp index 125f26bc54..e3e508b52d 100644 --- a/bpf/netd/BpfHandler.cpp +++ b/bpf/netd/BpfHandler.cpp @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -37,6 +36,10 @@ using base::unique_fd; using base::WaitForProperty; using bpf::getSocketCookie; using bpf::isAtLeastKernelVersion; +using bpf::isAtLeastT; +using bpf::isAtLeastU; +using bpf::isAtLeastV; +using bpf::isAtLeast25Q2; using bpf::queryProgram; using bpf::retrieveProgram; using netdutils::Status; @@ -72,18 +75,11 @@ static Status checkProgramAccessible(const char* programPath) { return netdutils::status::ok; } -// Checks if the device is running on release version of Android 25Q2 or newer. -static bool isAtLeast25Q2() { - return android_get_device_api_level() >= 36 || - (android_get_device_api_level() == 35 && - modules::sdklevel::detail::IsAtLeastPreReleaseCodename("Baklava")); -} - static Status initPrograms(const char* cg2_path) { if (!cg2_path) return Status("cg2_path is NULL"); // This code was mainlined in T, so this should be trivially satisfied. - if (!modules::sdklevel::IsAtLeastT()) return Status("S- platform is unsupported"); + if (!isAtLeastT) return Status("S- platform is unsupported"); // S requires eBPF support which was only added in 4.9, so this should be satisfied. if (!isAtLeastKernelVersion(4, 9, 0)) { @@ -91,22 +87,22 @@ static Status initPrograms(const char* cg2_path) { } // U bumps the kernel requirement up to 4.14 - if (modules::sdklevel::IsAtLeastU() && !isAtLeastKernelVersion(4, 14, 0)) { + if (isAtLeastU && !isAtLeastKernelVersion(4, 14, 0)) { return Status("U+ platform with kernel version < 4.14.0 is unsupported"); } // U mandates this mount point (though it should also be the case on T) - if (modules::sdklevel::IsAtLeastU() && !!strcmp(cg2_path, "/sys/fs/cgroup")) { + if (isAtLeastU && !!strcmp(cg2_path, "/sys/fs/cgroup")) { return Status("U+ platform with cg2_path != /sys/fs/cgroup is unsupported"); } // V bumps the kernel requirement up to 4.19 - if (modules::sdklevel::IsAtLeastV() && !isAtLeastKernelVersion(4, 19, 0)) { + if (isAtLeastV && !isAtLeastKernelVersion(4, 19, 0)) { return Status("V+ platform with kernel version < 4.19.0 is unsupported"); } // 25Q2 bumps the kernel requirement up to 5.4 - if (isAtLeast25Q2() && !isAtLeastKernelVersion(5, 4, 0)) { + if (isAtLeast25Q2 && !isAtLeastKernelVersion(5, 4, 0)) { return Status("25Q2+ platform with kernel version < 5.4.0 is unsupported"); } @@ -135,7 +131,7 @@ static Status initPrograms(const char* cg2_path) { cg_fd, BPF_CGROUP_INET_SOCK_RELEASE)); } - if (modules::sdklevel::IsAtLeastV()) { + if (isAtLeastV) { // V requires 4.19+, so technically this 2nd 'if' is not required, but it // doesn't hurt us to try to support AOSP forks that try to support older kernels. if (isAtLeastKernelVersion(4, 19, 0)) { @@ -180,7 +176,7 @@ static Status initPrograms(const char* cg2_path) { if (queryProgram(cg_fd, BPF_CGROUP_INET_SOCK_RELEASE) <= 0) abort(); } - if (modules::sdklevel::IsAtLeastV()) { + if (isAtLeastV) { // V requires 4.19+, so technically this 2nd 'if' is not required, but it // doesn't hurt us to try to support AOSP forks that try to support older kernels. if (isAtLeastKernelVersion(4, 19, 0)) { @@ -266,14 +262,13 @@ Status BpfHandler::init(const char* cg2_path) { // ...unless someone changed 'exec_start bpfloader' to 'start bpfloader' // in the rc file. // - // TODO: should be: if (!modules::sdklevel::IsAtLeastW()) - if (android_get_device_api_level() <= __ANDROID_API_V__) waitForBpf(); + if (!isAtLeast25Q2) waitForBpf(); RETURN_IF_NOT_OK(initPrograms(cg2_path)); RETURN_IF_NOT_OK(initMaps()); - if (android_get_device_api_level() > __ANDROID_API_V__) { - // make sure netd can create & write maps. sepolicy is V+, but enough to enforce on 25Q2+ + if (isAtLeast25Q2) { + // Make sure netd can create & write maps. sepolicy is V+, but enough to enforce on 25Q2+ int key = 1; int value = 123; unique_fd map(bpf::createMap(BPF_MAP_TYPE_ARRAY, sizeof(key), sizeof(value), 2, 0)); diff --git a/bpf/tests/mts/bpf_existence_test.cpp b/bpf/tests/mts/bpf_existence_test.cpp index 0ecda3de6d..75fb8e9f8c 100644 --- a/bpf/tests/mts/bpf_existence_test.cpp +++ b/bpf/tests/mts/bpf_existence_test.cpp @@ -31,6 +31,12 @@ using std::set; using std::string; using android::bpf::isAtLeastKernelVersion; +using android::bpf::isAtLeastR; +using android::bpf::isAtLeastS; +using android::bpf::isAtLeastT; +using android::bpf::isAtLeastU; +using android::bpf::isAtLeastV; +using android::bpf::isAtLeast25Q2; #define PLATFORM "/sys/fs/bpf/" #define TETHERING "/sys/fs/bpf/tethering/" @@ -42,16 +48,6 @@ using android::bpf::isAtLeastKernelVersion; class BpfExistenceTest : public ::testing::Test { }; -const bool unreleased = (android::base::GetProperty("ro.build.version.codename", "REL") != "REL"); -const int api_level = unreleased ? 10000 : android_get_device_api_level(); -const bool isAtLeastR = (api_level >= 30); -const bool isAtLeastS = (api_level >= 31); -// Sv2 is 32 -const bool isAtLeastT = (api_level >= 33); -const bool isAtLeastU = (api_level >= 34); -const bool isAtLeastV = (api_level >= 35); -const bool isAtLeast25Q2 = (api_level >= 36); - // Part of Android R platform (for 4.9+), but mainlined in S static const set PLATFORM_ONLY_IN_R = { PLATFORM "map_offload_tether_ingress_map", diff --git a/tests/unit/jni/Android.bp b/tests/unit/jni/Android.bp index 1a833e1772..1e9db03168 100644 --- a/tests/unit/jni/Android.bp +++ b/tests/unit/jni/Android.bp @@ -22,6 +22,7 @@ cc_library_shared { ], shared_libs: [ + "libbase", "liblog", "libnativehelper", "libnetdutils",