BpfMap: enforce BPF_F_RDWR_EXCLUSIVE doesn't use cached fd. am: 2f50623b0e

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/3134195

Change-Id: Ia0c699bc687c12589e42feb40f62391dcbce1a01
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Maciej Żenczykowski 2024-06-15 23:29:42 +00:00 • committed by Automerger Merge Worker
commit 74c8cff73d

View file

@ -15,6 +15,7 @@
*/
package com.android.net.module.util;
import static android.system.OsConstants.EBUSY;
import static android.system.OsConstants.EEXIST;
import static android.system.OsConstants.ENOENT;
@ -72,6 +73,12 @@ public class BpfMap<K extends Struct, V extends Struct> implements IBpfMap<K, V>
private static ConcurrentHashMap<Pair<String, Integer>, ParcelFileDescriptor> sFdCache =
new ConcurrentHashMap<>();
private static ParcelFileDescriptor checkModeExclusivity(ParcelFileDescriptor fd, int mode)
throws ErrnoException {
if (mode == BPF_F_RDWR_EXCLUSIVE) throw new ErrnoException("cachedBpfFdGet", EBUSY);
return fd;
}
private static ParcelFileDescriptor cachedBpfFdGet(String path, int mode,
int keySize, int valueSize)
throws ErrnoException, NullPointerException {
@ -82,12 +89,12 @@ public class BpfMap<K extends Struct, V extends Struct> implements IBpfMap<K, V>
var key = Pair.create(path, (mode << 26) ^ (keySize << 16) ^ valueSize);
// unlocked fetch is safe: map is concurrent read capable, and only inserted into
ParcelFileDescriptor fd = sFdCache.get(key);
if (fd != null) return fd;
if (fd != null) return checkModeExclusivity(fd, mode);
// ok, no cached fd present, need to grab a lock
synchronized (BpfMap.class) {
// need to redo the check
fd = sFdCache.get(key);
if (fd != null) return fd;
if (fd != null) return checkModeExclusivity(fd, mode);
// okay, we really haven't opened this before...
fd = ParcelFileDescriptor.adoptFd(nativeBpfFdGet(path, mode, keySize, valueSize));
sFdCache.put(key, fd);