CTS test for PingPongRoot vulnerability

Bug: 20770158
Change-Id: Ie4876ec8c374562cbeef6a2e50b5f9ae9b33ee4b
diff --git a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
index 00765c6..350309b 100644
--- a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
@@ -34,6 +34,7 @@
 #include <errno.h>
 #include <inttypes.h>
 #include <linux/sysctl.h>
+#include <arpa/inet.h>
 
 /*
  * Returns true iff this device is vulnerable to CVE-2013-2094.
@@ -227,6 +228,28 @@
     return !vulnerable;
 }
 
+static jboolean android_security_cts_NativeCodeTest_doPingPongRootTest(JNIEnv*, jobject)
+{
+    int icmp_sock;
+    struct sockaddr sock_addr;
+
+    memset(&sock_addr, 0, sizeof(sock_addr));
+    icmp_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
+    sock_addr.sa_family = AF_INET;
+
+    /* first connect */
+    connect(icmp_sock, &sock_addr, sizeof(sock_addr));
+
+    /* disconnect */
+    sock_addr.sa_family = AF_UNSPEC;
+    connect(icmp_sock, &sock_addr, sizeof(sock_addr));
+
+    /* second disconnect -> crash */
+    sock_addr.sa_family = AF_UNSPEC;
+    connect(icmp_sock, &sock_addr, sizeof(sock_addr));
+
+    return true;
+}
 
 static JNINativeMethod gMethods[] = {
     {  "doPerfEventTest", "()Z",
@@ -241,6 +264,8 @@
             (void *) android_security_cts_NativeCodeTest_doFutexTest },
     {  "doNvmapIocFromIdTest", "()Z",
             (void *) android_security_cts_NativeCodeTest_doNvmapIocFromIdTest },
+    {  "doPingPongRootTest", "()Z",
+            (void *) android_security_cts_NativeCodeTest_doPingPongRootTest },
 };
 
 int register_android_security_cts_NativeCodeTest(JNIEnv* env)
@@ -249,3 +274,4 @@
     return env->RegisterNatives(clazz, gMethods,
             sizeof(gMethods) / sizeof(JNINativeMethod));
 }
+
diff --git a/tests/tests/security/src/android/security/cts/NativeCodeTest.java b/tests/tests/security/src/android/security/cts/NativeCodeTest.java
index a2f8c09..ab41b4f 100644
--- a/tests/tests/security/src/android/security/cts/NativeCodeTest.java
+++ b/tests/tests/security/src/android/security/cts/NativeCodeTest.java
@@ -58,6 +58,12 @@
                    doNvmapIocFromIdTest());
     }
 
+    public void testPingPongRoot() throws Exception {
+        assertTrue("Device is vulnerable to CVE-2015-3636, a vulnerability in the ping "
+                   + "socket implementation. Please apply the security patch at "
+                   + "https://github.com/torvalds/linux/commit/a134f083e79f",
+                   doPingPongRootTest());
+    }
     /**
      * Returns true iff this device is vulnerable to CVE-2013-2094.
      * A patch for CVE-2013-2094 can be found at
@@ -120,4 +126,18 @@
      * false if the device is vulnerable.
      */
     private static native boolean doCVE20141710Test();
+
+    /**
+     * CVE-2015-3636
+     *
+     * Returns true if the patch is applied, crashes the system otherwise.
+     *
+     * Detects if the following patch is present.
+     * https://github.com/torvalds/linux/commit/a134f083e79f
+     *
+     * Credit: Wen Xu and wushi of KeenTeam.
+     * http://seclists.org/oss-sec/2015/q2/333
+     */
+    private static native boolean doPingPongRootTest();
+
 }