Merge "CTS test for Android Security b/27275324 b/72508461" into nyc-dev
diff --git a/tests/tests/security/res/raw/bug_63522067_1_hevc.mp4 b/tests/tests/security/res/raw/bug_63522067_1_hevc.mp4
deleted file mode 100644
index 261e173..0000000
--- a/tests/tests/security/res/raw/bug_63522067_1_hevc.mp4
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_63522067_2_hevc.mp4 b/tests/tests/security/res/raw/bug_63522067_2_hevc.mp4
deleted file mode 100644
index e8f1c41..0000000
--- a/tests/tests/security/res/raw/bug_63522067_2_hevc.mp4
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_63522067_3_hevc.mp4 b/tests/tests/security/res/raw/bug_63522067_3_hevc.mp4
deleted file mode 100644
index ecc10cb..0000000
--- a/tests/tests/security/res/raw/bug_63522067_3_hevc.mp4
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_63522067_4_hevc.mp4 b/tests/tests/security/res/raw/bug_63522067_4_hevc.mp4
deleted file mode 100644
index 34851ad..0000000
--- a/tests/tests/security/res/raw/bug_63522067_4_hevc.mp4
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java b/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
index dc74708..a5f03f8 100644
--- a/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
+++ b/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
@@ -34,116 +34,219 @@
 public class AmbiguousBundlesTest extends AndroidTestCase {
 
     @SecurityTest
+    public void test_android_CVE_2017_13311() throws Exception {
+        Ambiguator ambiguator = new Ambiguator() {
+            @Override
+            public Bundle make(Bundle preReSerialize, Bundle postReSerialize) throws Exception {
+               Random random = new Random(1234);
+               int minHash = 0;
+                for (String s : preReSerialize.keySet()) {
+                    minHash = Math.min(minHash, s.hashCode());
+                }
+                for (String s : postReSerialize.keySet()) {
+                    minHash = Math.min(minHash, s.hashCode());
+                }
+
+                String key;
+                int keyHash;
+
+                do {
+                    key = randomString(random);
+                    keyHash = key.hashCode();
+                } while (keyHash >= minHash);
+
+                padBundle(postReSerialize, preReSerialize.size(), minHash, random);
+                padBundle(preReSerialize, postReSerialize.size(), minHash, random);
+
+                Parcel parcel = Parcel.obtain();
+
+                parcel.writeInt(preReSerialize.size() + 1);
+                parcel.writeString(key);
+
+                parcel.writeInt(VAL_OBJECTARRAY);
+                parcel.writeInt(3);
+
+                parcel.writeInt(VAL_PARCELABLE);
+                parcel.writeString("com.android.internal.app.procstats.ProcessStats");
+
+                parcel.writeInt(PROCSTATS_MAGIC);
+                parcel.writeInt(PROCSTATS_PARCEL_VERSION);
+                parcel.writeInt(PROCSTATS_STATE_COUNT);
+                parcel.writeInt(PROCSTATS_ADJ_COUNT);
+                parcel.writeInt(PROCSTATS_PSS_COUNT);
+                parcel.writeInt(PROCSTATS_SYS_MEM_USAGE_COUNT);
+                parcel.writeInt(PROCSTATS_SPARSE_MAPPING_TABLE_ARRAY_SIZE);
+
+                parcel.writeLong(0);
+                parcel.writeLong(0);
+                parcel.writeLong(0);
+                parcel.writeLong(0);
+                parcel.writeLong(0);
+                parcel.writeString(null);
+                parcel.writeInt(0);
+                parcel.writeInt(0);
+
+                parcel.writeInt(0);
+                parcel.writeInt(0);
+                parcel.writeInt(1);
+                parcel.writeInt(1);
+                parcel.writeInt(0);
+
+                for (int i = 0; i < PROCSTATS_ADJ_COUNT; i++) {
+                    parcel.writeInt(0);
+                }
+
+                parcel.writeInt(0);
+                parcel.writeInt(1);
+                parcel.writeInt(0);
+
+                parcel.writeInt(0);
+                parcel.writeInt(0);
+                parcel.writeInt(1);
+                parcel.writeInt(VAL_LONGARRAY);
+                parcel.writeString("AAAAA");
+                parcel.writeInt(0);
+
+                parcel.writeInt(VAL_INTEGER);
+                parcel.writeInt(0);
+                parcel.writeInt(VAL_BUNDLE);
+                parcel.writeBundle(postReSerialize);
+
+                writeBundleSkippingHeaders(parcel, preReSerialize);
+
+                parcel.setDataPosition(0);
+                Bundle bundle = new Bundle();
+                parcelledDataField.set(bundle, parcel);
+                return bundle;
+            }
+
+            @Override
+            protected String makeStringToInject(Bundle stuffToInject, Random random) {
+                return null;
+            }
+        };
+
+        testAmbiguator(ambiguator);
+    }
+
+    @SecurityTest
     public void test_android_CVE_2017_13287() throws Exception {
+        Ambiguator ambiguator = new Ambiguator() {
+            @Override
+            public Bundle make(Bundle preReSerialize, Bundle postReSerialize) throws Exception {
+                Random random = new Random(1234);
+                int minHash = 0;
+                for (String s : preReSerialize.keySet()) {
+                    minHash = Math.min(minHash, s.hashCode());
+                }
+                for (String s : postReSerialize.keySet()) {
+                    minHash = Math.min(minHash, s.hashCode());
+                }
+
+                String key;
+                int keyHash;
+
+                do {
+                    key = randomString(random);
+                    keyHash = key.hashCode();
+                } while (keyHash >= minHash);
+
+                padBundle(postReSerialize, preReSerialize.size() + 1, minHash, random);
+                padBundle(preReSerialize, postReSerialize.size() - 1, minHash, random);
+
+                String key2;
+                int key2Hash;
+                do {
+                    key2 = makeStringToInject(postReSerialize, random);
+                    key2Hash = key2.hashCode();
+                } while (key2Hash >= minHash || key2Hash <= keyHash);
+
+
+                Parcel parcel = Parcel.obtain();
+
+                parcel.writeInt(preReSerialize.size() + 2);
+                parcel.writeString(key);
+
+                parcel.writeInt(VAL_PARCELABLE);
+                parcel.writeString("com.android.internal.widget.VerifyCredentialResponse");
+
+                parcel.writeInt(0);
+                parcel.writeInt(0);
+
+                parcel.writeString(key2);
+                parcel.writeInt(VAL_NULL);
+
+                writeBundleSkippingHeaders(parcel, preReSerialize);
+
+                parcel.setDataPosition(0);
+                Bundle bundle = new Bundle();
+                parcelledDataField.set(bundle, parcel);
+                return bundle;
+            }
+
+            @Override
+            protected String makeStringToInject(Bundle stuffToInject, Random random) {
+                Parcel p = Parcel.obtain();
+                p.writeInt(0);
+                p.writeInt(0);
+
+                Parcel p2 = Parcel.obtain();
+                stuffToInject.writeToParcel(p2, 0);
+                int p2Len = p2.dataPosition() - BUNDLE_SKIP;
+
+                for (int i = 0; i < p2Len / 4 + 4; i++) {
+                    int paddingVal;
+                    if (i > 3) {
+                        paddingVal = i;
+                    } else {
+                        paddingVal = random.nextInt();
+                    }
+                    p.writeInt(paddingVal);
+
+                }
+
+                p.appendFrom(p2, BUNDLE_SKIP, p2Len);
+                p2.recycle();
+
+                while (p.dataPosition() % 8 != 0) p.writeInt(0);
+                for (int i = 0; i < 2; i++) {
+                    p.writeInt(0);
+                }
+
+                int len = p.dataPosition() / 2 - 1;
+                p.writeInt(0); p.writeInt(0);
+                p.setDataPosition(0);
+                p.writeInt(len);
+                p.writeInt(len);
+                p.setDataPosition(0);
+                String result = p.readString();
+                p.recycle();
+                return result;
+            }
+        };
+
+        testAmbiguator(ambiguator);
+    }
+
+    private void testAmbiguator(Ambiguator ambiguator) {
         Bundle bundle;
-        {
-            Bundle verifyMe = new Bundle();
-            verifyMe.putString("cmd", "something_safe");
-            Bundle useMe = new Bundle();
-            useMe.putString("cmd", "replaced_thing");
-            Ambiguator a = new Ambiguator() {
-                @Override
-                public Bundle make(Bundle preReSerialize, Bundle postReSerialize) throws Exception {
-                    Random random = new Random(1234);
-                    int minHash = 0;
-                    for (String s : preReSerialize.keySet()) {
-                        minHash = Math.min(minHash, s.hashCode());
-                    }
-                    for (String s : postReSerialize.keySet()) {
-                        minHash = Math.min(minHash, s.hashCode());
-                    }
+        Bundle verifyMe = new Bundle();
+        verifyMe.putString("cmd", "something_safe");
+        Bundle useMe = new Bundle();
+        useMe.putString("cmd", "replaced_thing");
 
-                    String key;
-                    int keyHash;
+        try {
+            bundle = ambiguator.make(verifyMe, useMe);
 
-                    do {
-                        key = randomString(random);
-                        keyHash = key.hashCode();
-                    } while (keyHash >= minHash);
+            bundle = reparcel(bundle);
+            String value1 = bundle.getString("cmd");
+            bundle = reparcel(bundle);
+            String value2 = bundle.getString("cmd");
 
-                    padBundle(postReSerialize, preReSerialize.size() + 1, minHash, random);
-                    padBundle(preReSerialize, postReSerialize.size() - 1, minHash, random);
-
-                    String key2;
-                    int key2Hash;
-                    do {
-                        key2 = makeStringToInject(postReSerialize, random);
-                        key2Hash = key2.hashCode();
-                    } while (key2Hash >= minHash || key2Hash <= keyHash);
-
-
-                    Parcel parcel = Parcel.obtain();
-
-                    parcel.writeInt(preReSerialize.size() + 2);
-                    parcel.writeString(key);
-
-                    parcel.writeInt(VAL_PARCELABLE);
-                    parcel.writeString("com.android.internal.widget.VerifyCredentialResponse");
-
-                    parcel.writeInt(0);
-                    parcel.writeInt(0);
-
-                    parcel.writeString(key2);
-                    parcel.writeInt(VAL_NULL);
-
-                    writeBundleSkippingHeaders(parcel, preReSerialize);
-
-                    parcel.setDataPosition(0);
-                    Bundle bundle = new Bundle();
-                    parcelledDataField.set(bundle, parcel);
-                    return bundle;
-                }
-
-                @Override
-                protected String makeStringToInject(Bundle stuffToInject, Random random) {
-                    Parcel p = Parcel.obtain();
-                    p.writeInt(0);
-                    p.writeInt(0);
-
-                    Parcel p2 = Parcel.obtain();
-                    stuffToInject.writeToParcel(p2, 0);
-                    int p2Len = p2.dataPosition() - BUNDLE_SKIP;
-
-                    for (int i = 0; i < p2Len / 4 + 4; i++) {
-                        int paddingVal;
-                        if (i > 3) {
-                            paddingVal = i;
-                        } else {
-                            paddingVal = random.nextInt();
-                        }
-                        p.writeInt(paddingVal);
-
-                    }
-
-                    p.appendFrom(p2, BUNDLE_SKIP, p2Len);
-                    p2.recycle();
-
-                    while (p.dataPosition() % 8 != 0) p.writeInt(0);
-                    for (int i = 0; i < 2; i++) {
-                        p.writeInt(0);
-                    }
-
-                    int len = p.dataPosition() / 2 - 1;
-                    p.writeInt(0); p.writeInt(0);
-                    p.setDataPosition(0);
-                    p.writeInt(len);
-                    p.writeInt(len);
-                    p.setDataPosition(0);
-                    String result = p.readString();
-                    p.recycle();
-                    return result;
-                }
-            };
-            bundle = a.make(verifyMe, useMe);
-        }
-
-        bundle = reparcel(bundle);
-        String value1 = bundle.getString("cmd");
-        bundle = reparcel(bundle);
-        String value2 = bundle.getString("cmd");
-
-        if (!value1.equals(value2)) {
-            fail("String " + value1 + "!=" + value2 + " after reparceling.");
+            if (!value1.equals(value2)) {
+                fail("String " + value1 + "!=" + value2 + " after reparceling.");
+            }
+        } catch (Exception e) {
         }
     }
 
@@ -159,10 +262,23 @@
 
     static abstract class Ambiguator {
 
-        protected static final int VAL_PARCELABLE = 4;
         protected static final int VAL_NULL = -1;
+        protected static final int VAL_INTEGER = 1;
+        protected static final int VAL_BUNDLE = 3;
+        protected static final int VAL_PARCELABLE = 4;
+        protected static final int VAL_OBJECTARRAY = 17;
+        protected static final int VAL_INTARRAY = 18;
+        protected static final int VAL_LONGARRAY = 19;
         protected static final int BUNDLE_SKIP = 12;
 
+        protected static final int PROCSTATS_MAGIC = 0x50535454;
+        protected static final int PROCSTATS_PARCEL_VERSION = 21;
+        protected static final int PROCSTATS_STATE_COUNT = 14;
+        protected static final int PROCSTATS_ADJ_COUNT = 8;
+        protected static final int PROCSTATS_PSS_COUNT = 7;
+        protected static final int PROCSTATS_SYS_MEM_USAGE_COUNT = 16;
+        protected static final int PROCSTATS_SPARSE_MAPPING_TABLE_ARRAY_SIZE = 4096;
+
         protected final Field parcelledDataField;
 
         public Ambiguator() throws Exception {
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index e6111af..85e833c 100755
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -544,14 +544,6 @@
     }
 
     @SecurityTest
-    public void testStagefright_bug_63522067() throws Exception {
-        doStagefrightTestRawBlob(R.raw.bug_63522067_1_hevc, "video/hevc", 320, 420);
-        doStagefrightTestRawBlob(R.raw.bug_63522067_2_hevc, "video/hevc", 320, 420);
-        doStagefrightTestRawBlob(R.raw.bug_63522067_3_hevc, "video/hevc", 320, 420);
-        doStagefrightTestRawBlob(R.raw.bug_63522067_4_hevc, "video/hevc", 320, 420);
-    }
-
-    @SecurityTest
     public void testStagefright_bug_25765591() throws Exception {
         doStagefrightTest(R.raw.bug_25765591);
     }
diff --git a/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java b/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
index 68d944b..2996c76 100644
--- a/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
+++ b/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
@@ -69,6 +69,7 @@
     public static final String STOP_LOADING_URL = "webkit/test_stop_loading.html";
     public static final String BLANK_TAG_URL = "webkit/blank_tag.html";
     public static final String PAGE_WITH_LINK_URL = "webkit/page_with_link.html";
+    public static final String URL_IN_PAGE_WITH_LINK = "http://foo.com/";
     // Not a real page, just triggers a 404 response.
     public static final String NON_EXISTENT_PAGE_URL = "webkit/generate_404.html";
     public static final String BAD_IMAGE_PAGE_URL = "webkit/test_bad_image_url.html";
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
index 2f99b49..b480781 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
@@ -129,6 +129,7 @@
 
         final WebView childWebView = mOnUiThread.createWebView();
 
+        WebViewOnUiThread childWebViewOnUiThread = new WebViewOnUiThread(this, childWebView);
         mOnUiThread.setWebChromeClient(new WebChromeClient() {
             @Override
             public boolean onCreateWindow(
@@ -144,21 +145,26 @@
                 return true;
             }
         });
-        mOnUiThread.loadUrl(mWebServer.getAssetUrl(TestHtmlConstants.BLANK_TAG_URL));
+        {
+          final int childCallCount = childWebViewClient.getShouldOverrideUrlLoadingCallCount();
+          mOnUiThread.loadUrl(mWebServer.getAssetUrl(TestHtmlConstants.BLANK_TAG_URL));
 
-        new PollingCheck(TEST_TIMEOUT) {
-            @Override
-            protected boolean check() {
-                return childWebViewClient.hasOnPageFinishedCalled();
-            }
-        }.run();
-        assertEquals(mWebServer.getAssetUrl(TestHtmlConstants.PAGE_WITH_LINK_URL),
-                childWebViewClient.getLastShouldOverrideUrl());
+          new PollingCheck(TEST_TIMEOUT) {
+              @Override
+              protected boolean check() {
+                  return childWebViewClient.hasOnPageFinishedCalled();
+              }
+          }.run();
+          new PollingCheck(TEST_TIMEOUT) {
+              @Override
+              protected boolean check() {
+                  return childWebViewClient.getShouldOverrideUrlLoadingCallCount() > childCallCount;
+              }
+          }.run();
+          assertEquals(mWebServer.getAssetUrl(TestHtmlConstants.PAGE_WITH_LINK_URL),
+                  childWebViewClient.getLastShouldOverrideUrl());
+        }
 
-        // Now test a navigation within the page
-        //TODO(hush) Enable this portion when b/12804986 is fixed.
-        /*
-        WebViewOnUiThread childWebViewOnUiThread = new WebViewOnUiThread(this, childWebView);
         final int childCallCount = childWebViewClient.getShouldOverrideUrlLoadingCallCount();
         final int mainCallCount = mainWebViewClient.getShouldOverrideUrlLoadingCallCount();
         clickOnLinkUsingJs("link", childWebViewOnUiThread);
@@ -169,8 +175,8 @@
             }
         }.run();
         assertEquals(mainCallCount, mainWebViewClient.getShouldOverrideUrlLoadingCallCount());
-        assertEquals(TEST_URL, childWebViewClient.getLastShouldOverrideUrl());
-        */
+        assertEquals(
+            TestHtmlConstants.URL_IN_PAGE_WITH_LINK, childWebViewClient.getLastShouldOverrideUrl());
     }
 
     private void clickOnLinkUsingJs(final String linkId, WebViewOnUiThread webViewOnUiThread) {
@@ -685,7 +691,6 @@
         @Override
         public void onLoadResource(WebView view, String url) {
             super.onLoadResource(view, url);
-            assertTrue(mOnPageStartedCalled);
             mOnLoadResourceCalled = true;
         }