From c350db788ac68d641e15403ddab379f3155aff41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Wed, 8 Nov 2023 23:40:50 -0800 Subject: [PATCH] switch SynchronizeKernelRCU back to jni - but from BpfMap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit we can't use java for this, because pre-U-QPR2 does not include: https://android-review.googlesource.com/c/platform/system/sepolicy/+/2821590 system_server dontaudit key_socket getopt so we'll spew lots of: 11-08 07:52:43.776 1469 1469 I auditd : type=1400 audit(0.0:4): avc: denied { getopt } for comm="system_server" scontext=u:r:system_server:s0 tcontext=u:r:system_server:s0 tclass=key_socket permissive=0 11-08 07:52:44.360 1469 1469 I auditd : type=1400 audit(0.0:5): avc: denied { getopt } for comm="NetworkStats" scontext=u:r:system_server:s0 tcontext=u:r:system_server:s0 tclass=key_socket permissive=0 11-08 07:52:44.508 1469 1469 I auditd : type=1400 audit(0.0:7): avc: denied { getopt } for comm="android.bg" scontext=u:r:system_server:s0 tcontext=u:r:system_server:s0 tclass=key_socket permissive=0 and the like. This is due to Java's Os.close() in: libcore/luni/src/main/java/libcore/io/BlockGuardOs.java;l=100 calling: if (fd.isSocket$()) if (isLingerSocket(fd)) ... Test: TreeHugger Signed-off-by: Maciej Żenczykowski Change-Id: Ib87fa5e8f0dfd9fbbccb25fb58a9fa78d6a07111 --- .../src/com/android/server/BpfNetMaps.java | 14 +------------ .../com/android/net/module/util/BpfMap.java | 7 +++++++ .../com_android_net_module_util_BpfMap.cpp | 20 +++++++++++++++++++ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java index 086d276c00..ad9cfbe10e 100644 --- a/service/src/com/android/server/BpfNetMaps.java +++ b/service/src/com/android/server/BpfNetMaps.java @@ -45,8 +45,6 @@ import static android.system.OsConstants.EINVAL; import static android.system.OsConstants.ENODEV; import static android.system.OsConstants.ENOENT; import static android.system.OsConstants.EOPNOTSUPP; -import static android.system.OsConstants.SOCK_RAW; -import static android.system.OsConstants.SOCK_CLOEXEC; import static com.android.server.ConnectivityStatsLog.NETWORK_BPF_MAP_INFO; @@ -327,19 +325,9 @@ public class BpfNetMaps { */ @RequiresApi(Build.VERSION_CODES.TIRAMISU) public int synchronizeKernelRCU() { - // See p/m/C's staticlibs/native/bpf_headers/include/bpf/BpfUtils.h - // for equivalent C implementation of this function. try { - // When closing socket, kernel calls synchronize_rcu() - // from pf_key's sock_release(). - // Constants from //bionic/libc/include/sys/socket.h: AF_KEY=15 - // and kernel's include/uapi/linux/pfkeyv2.h: PF_KEY_V2=2 - Os.close(Os.socket(15 /*PF_KEY*/, SOCK_RAW | SOCK_CLOEXEC, 2)); + BpfMap.synchronizeKernelRCU(); } catch (ErrnoException e) { - // socket() can only fail due to lack of privs (selinux) or OOM, - // close() always succeeds, but may return a pending error, - // however on a freshly opened socket that cannot happen. - // As such this failing is basically a build configuration error. return -e.errno; } return 0; diff --git a/staticlibs/device/com/android/net/module/util/BpfMap.java b/staticlibs/device/com/android/net/module/util/BpfMap.java index 595ac7427d..d622427882 100644 --- a/staticlibs/device/com/android/net/module/util/BpfMap.java +++ b/staticlibs/device/com/android/net/module/util/BpfMap.java @@ -239,6 +239,11 @@ public class BpfMap implements IBpfMap return Struct.parse(mValueClass, buffer); } + /** Synchronize Kernel RCU */ + public static void synchronizeKernelRCU() throws ErrnoException { + nativeSynchronizeKernelRCU(); + } + private static native int nativeBpfFdGet(String path, int mode, int keySize, int valueSize) throws ErrnoException, NullPointerException; @@ -260,4 +265,6 @@ public class BpfMap implements IBpfMap private native boolean nativeFindMapEntry(int fd, byte[] key, byte[] value) throws ErrnoException; + + private static native void nativeSynchronizeKernelRCU() throws ErrnoException; } diff --git a/staticlibs/native/bpfmapjni/com_android_net_module_util_BpfMap.cpp b/staticlibs/native/bpfmapjni/com_android_net_module_util_BpfMap.cpp index f93d6e1757..b92f1070b8 100644 --- a/staticlibs/native/bpfmapjni/com_android_net_module_util_BpfMap.cpp +++ b/staticlibs/native/bpfmapjni/com_android_net_module_util_BpfMap.cpp @@ -15,6 +15,8 @@ */ #include +#include +#include #include #include #include @@ -117,6 +119,22 @@ static jboolean com_android_net_module_util_BpfMap_nativeFindMapEntry(JNIEnv *en return throwIfNotEnoent(env, "nativeFindMapEntry", ret, errno); } +static void com_android_net_module_util_BpfMap_nativeSynchronizeKernelRCU(JNIEnv *env, + jclass clazz) { + const int pfSocket = socket(AF_KEY, SOCK_RAW | SOCK_CLOEXEC, PF_KEY_V2); + + if (pfSocket < 0) { + jniThrowErrnoException(env, "nativeSynchronizeKernelRCU:socket", errno); + return; + } + + if (close(pfSocket)) { + jniThrowErrnoException(env, "nativeSynchronizeKernelRCU:close", errno); + return; + } + return; +} + /* * JNI registration. */ @@ -132,6 +150,8 @@ static const JNINativeMethod gMethods[] = { (void*) com_android_net_module_util_BpfMap_nativeGetNextMapKey }, { "nativeFindMapEntry", "(I[B[B)Z", (void*) com_android_net_module_util_BpfMap_nativeFindMapEntry }, + { "nativeSynchronizeKernelRCU", "()V", + (void*) com_android_net_module_util_BpfMap_nativeSynchronizeKernelRCU }, };