From 9eca02a8fa20aa14920f0dd3bf88c06ce04a2575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Fri, 14 Jun 2024 15:15:23 -0700 Subject: [PATCH] make java maps grab locks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The java bpfmap fd cache has some implications: - this won't protect against two SingleWriterBpfMap instantiations for the same map (path) in the same process - we don't release any locks on BpfMap destruction. Test: TreeHugger Signed-off-by: Maciej Żenczykowski Change-Id: Ibb0b1f57974c307ea5e0fa699ce8d598c59f456e --- .../com/android/net/module/util/BpfMap.java | 3 +++ .../net/module/util/SingleWriterBpfMap.java | 2 +- .../com_android_net_module_util_BpfMap.cpp | 19 ++++++++++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/staticlibs/device/com/android/net/module/util/BpfMap.java b/staticlibs/device/com/android/net/module/util/BpfMap.java index da77ae8860..dafff20404 100644 --- a/staticlibs/device/com/android/net/module/util/BpfMap.java +++ b/staticlibs/device/com/android/net/module/util/BpfMap.java @@ -52,6 +52,9 @@ public class BpfMap implements IBpfMap public static final int BPF_F_RDONLY = 1 << 3; public static final int BPF_F_WRONLY = 1 << 4; + // magic value for jni consumption, invalid from kernel point of view + public static final int BPF_F_RDWR_EXCLUSIVE = BPF_F_RDONLY | BPF_F_WRONLY; + public static final int BPF_MAP_TYPE_HASH = 1; private static final int BPF_F_NO_PREALLOC = 1; diff --git a/staticlibs/device/com/android/net/module/util/SingleWriterBpfMap.java b/staticlibs/device/com/android/net/module/util/SingleWriterBpfMap.java index 254995fae2..bbd921d179 100644 --- a/staticlibs/device/com/android/net/module/util/SingleWriterBpfMap.java +++ b/staticlibs/device/com/android/net/module/util/SingleWriterBpfMap.java @@ -63,7 +63,7 @@ public class SingleWriterBpfMap extends BpfM public SingleWriterBpfMap(@NonNull final String path, final Class key, final Class value) throws ErrnoException, NullPointerException { - super(path, BPF_F_RDWR, key, value); + super(path, BPF_F_RDWR_EXCLUSIVE, key, value); // Populate cache with the current map contents. K currentKey = super.getFirstKey(); 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 b92f1070b8..1923ceb139 100644 --- a/staticlibs/native/bpfmapjni/com_android_net_module_util_BpfMap.cpp +++ b/staticlibs/native/bpfmapjni/com_android_net_module_util_BpfMap.cpp @@ -35,7 +35,24 @@ static jint com_android_net_module_util_BpfMap_nativeBpfFdGet(JNIEnv *env, jclas jstring path, jint mode, jint keySize, jint valueSize) { ScopedUtfChars pathname(env, path); - jint fd = bpf::bpfFdGet(pathname.c_str(), static_cast(mode)); + jint fd = -1; + switch (mode) { + case 0: + fd = bpf::mapRetrieveRW(pathname.c_str()); + break; + case BPF_F_RDONLY: + fd = bpf::mapRetrieveRO(pathname.c_str()); + break; + case BPF_F_WRONLY: + fd = bpf::mapRetrieveWO(pathname.c_str()); + break; + case BPF_F_RDONLY|BPF_F_WRONLY: + fd = bpf::mapRetrieveExclusiveRW(pathname.c_str()); + break; + default: + errno = EINVAL; + break; + } if (fd < 0) { jniThrowErrnoException(env, "nativeBpfFdGet", errno);