verify java map key/value struct size matches file descriptor

(this should avoid kernel reading/writing from out of bounds)

Test: TreeHugger
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I71fe71eee4e4e6a917477eef5fd2266439e803f3
diff --git a/staticlibs/native/bpfmapjni/Android.bp b/staticlibs/native/bpfmapjni/Android.bp
index cd254d4..8babcce 100644
--- a/staticlibs/native/bpfmapjni/Android.bp
+++ b/staticlibs/native/bpfmapjni/Android.bp
@@ -23,7 +23,7 @@
         "com_android_net_module_util_TcUtils.cpp",
     ],
     header_libs: [
-        "bpf_syscall_wrappers",
+        "bpf_headers",
         "jni_headers",
     ],
     shared_libs: [
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 2e88fc8..2146d17 100644
--- a/staticlibs/native/bpfmapjni/com_android_net_module_util_BpfMap.cpp
+++ b/staticlibs/native/bpfmapjni/com_android_net_module_util_BpfMap.cpp
@@ -25,15 +25,34 @@
 #define BPF_FD_JUST_USE_INT
 #include "BpfSyscallWrappers.h"
 
+#include "bpf/KernelVersion.h"
+
 namespace android {
 
 static jint com_android_net_module_util_BpfMap_nativeBpfFdGet(JNIEnv *env, jclass clazz,
-        jstring path, jint mode) {
+        jstring path, jint mode, jint keySize, jint valueSize) {
     ScopedUtfChars pathname(env, path);
 
     jint fd = bpf::bpfFdGet(pathname.c_str(), static_cast<unsigned>(mode));
 
-    if (fd < 0) jniThrowErrnoException(env, "nativeBpfFdGet", errno);
+    if (fd < 0) {
+        jniThrowErrnoException(env, "nativeBpfFdGet", errno);
+        return -1;
+    }
+
+    if (bpf::isAtLeastKernelVersion(4, 14, 0)) {
+        // These likely fail with -1 and set errno to EINVAL on <4.14
+        if (bpf::bpfGetFdKeySize(fd) != keySize) {
+            close(fd);
+            jniThrowErrnoException(env, "nativeBpfFdGet KeySize", EBADFD);
+            return -1;
+        }
+        if (bpf::bpfGetFdValueSize(fd) != valueSize) {
+            close(fd);
+            jniThrowErrnoException(env, "nativeBpfFdGet ValueSize", EBADFD);
+            return -1;
+        }
+    }
 
     return fd;
 }
@@ -103,7 +122,7 @@
  */
 static const JNINativeMethod gMethods[] = {
     /* name, signature, funcPtr */
-    { "nativeBpfFdGet", "(Ljava/lang/String;I)I",
+    { "nativeBpfFdGet", "(Ljava/lang/String;III)I",
         (void*) com_android_net_module_util_BpfMap_nativeBpfFdGet },
     { "nativeWriteToMapEntry", "(I[B[BI)V",
         (void*) com_android_net_module_util_BpfMap_nativeWriteToMapEntry },