disallow 32-bit *system* userspace on 6.2+

https://android-developers.googleblog.com/2022/09/optimize-for-android-go-lessons-from-google-apps-part-1.html

Year   Android   MinRAM
2017   8/O       512 MB
2018   9/P       512 MB
2019   10/Q      512 MB
2020   11/R      1 GB
2021   12/S      1 GB
2022   13/T      2 GB

More than 4GB (and really even ~3..3.5 GB) of ram basically
requires a 64-bit kernel, as no one wants to deal with
debugging PAE kernel complexities.

Devices newly launching on 2023's Android 14/U must use
a 64-bit kernel.  5.15 LTS is highest supported by T.
Hence 5.16+ must be a 64-bit kernel.
(see vts_kernel_isa_test.cpp)

Note:

This change doesn't take effect until 2024's Android 15/V,
and only then on the latest 6.~6 LTS, which will only be used
with the latest SoCs, and will thus only affect the latest
and thus premium devices (which likely have 10+ GB).
By the time these 6.6 using SoCs reach lower end devices,
it'll be 2026 or later, at which point I expect even
low end devices will have 4+GB.

Additionally note that technically this only affects
mainline using devices.  Non mainline usecases can
be customized (ie. for example this change reverted)
by oems/vendors however they wish.  Although we
won't be providing support (but considering the
existing state of 32-bit testing, that's already
pretty much the case).

Test: TreeHugger
Bug: 163141236
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I64f5db5a440465f0b48368815fea3029619a9681
diff --git a/netd/BpfHandler.cpp b/netd/BpfHandler.cpp
index fb6d5b8..a090a54 100644
--- a/netd/BpfHandler.cpp
+++ b/netd/BpfHandler.cpp
@@ -85,8 +85,24 @@
     // U bumps the kernel requirement up to 4.14
     if (modules::sdklevel::IsAtLeastU() && !bpf::isAtLeastKernelVersion(4, 14, 0)) abort();
 
-    // V bumps the kernel requirement up to 4.19
-    if (modules::sdklevel::IsAtLeastV() && !bpf::isAtLeastKernelVersion(4, 19, 0)) abort();
+    if (modules::sdklevel::IsAtLeastV()) {
+        // V bumps the kernel requirement up to 4.19
+        // see also: //system/netd/tests/kernel_test.cpp TestKernel419
+        if (!bpf::isAtLeastKernelVersion(4, 19, 0)) abort();
+
+        // Technically already required by U, but only enforce on V+
+        // see also: //system/netd/tests/kernel_test.cpp TestKernel64Bit
+        if (bpf::isKernel32Bit() && bpf::isAtLeastKernelVersion(5, 16, 0)) abort();
+    }
+
+    // Linux 6.1 is highest version supported by U, starting with V new kernels,
+    // ie. 6.2+ we are dropping various kernel/system userspace 32-on-64 hacks
+    // (for example "ANDROID: xfrm: remove in_compat_syscall() checks").
+    // Note: this check/enforcement only applies to *system* userspace code,
+    // it does not affect unprivileged apps, the 32-on-64 compatibility
+    // problems are AFAIK limited to various CAP_NET_ADMIN protected interfaces.
+    // see also: //system/bpf/bpfloader/BpfLoader.cpp main()
+    if (bpf::isUserspace32bit() && bpf::isAtLeastKernelVersion(6, 2, 0)) abort();
 
     // U mandates this mount point (though it should also be the case on T)
     if (modules::sdklevel::IsAtLeastU() && !!strcmp(cg2_path, "/sys/fs/cgroup")) abort();