diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2018-11-20 19:35:42 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-11-20 19:35:42 +0000 |
commit | 6d549abdf13666dee95cf9ee1d22ea5501aa0486 (patch) | |
tree | 74eea765bc16a22fac92f7d31b7b050efabf106f | |
parent | a46868fca645ed193ec15c6790ccb970dd81d495 (diff) | |
parent | 36ac203ccee730c89e7cd4dfa46ad4455719c19b (diff) | |
download | cts-6d549abdf13666dee95cf9ee1d22ea5501aa0486.tar.gz |
Merge "DO NOT MERGE: Remove ClonedSecureRandomTest" into marshmallow-cts-dev
-rw-r--r-- | tests/tests/security/src/android/security/cts/ClonedSecureRandomTest.java | 266 |
1 files changed, 0 insertions, 266 deletions
diff --git a/tests/tests/security/src/android/security/cts/ClonedSecureRandomTest.java b/tests/tests/security/src/android/security/cts/ClonedSecureRandomTest.java deleted file mode 100644 index 4ee1480c493..00000000000 --- a/tests/tests/security/src/android/security/cts/ClonedSecureRandomTest.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security.cts; - -import android.app.ActivityManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.RemoteException; -import android.os.IBinder; -import android.security.cts.activity.ISecureRandomService; -import android.security.cts.activity.SecureRandomService; -import android.test.AndroidTestCase; - -import com.android.cts.util.TimeoutReq; - -import java.io.BufferedReader; -import java.io.EOFException; -import java.io.FileReader; -import java.io.IOException; -import java.util.Arrays; -import java.util.BitSet; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -public class ClonedSecureRandomTest extends AndroidTestCase { - private static final int MAX_SHUTDOWN_TRIES = 50; - - private static final int ANSWER_TIMEOUT_SECONDS = 180; - - private static final String SEPARATE_PROCESS_NAME = ":secureRandom"; - - private static final int MAX_PID = 32768; - - /** - * Attempt to burn through PIDs faster after this many iterations to reach a - * wrap-around point faster. - */ - private static final int PRIMING_ITERATIONS = 128; - - private static final int RANDOM_BYTES_PER_PID = 8; - - private static final int MAX_PIDS_WASTED = 1024; - - private static final int PID_WASTING_SKIP_LOWER = 64; - - private static final int PID_WASTING_SKIP_UPPER = 2048; - - private volatile CountDownLatch mLatch; - - private Intent mSeparateIntent; - - private ISecureRandomService mSecureRandomService; - - private ServiceConnection mServiceConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName className, IBinder service) { - mSecureRandomService = ISecureRandomService.Stub.asInterface(service); - mLatch.countDown(); - } - - public void onServiceDisconnected(ComponentName className) { - } - }; - - private boolean mHasDisconnected; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - mSeparateIntent = new Intent(getContext(), SecureRandomService.class); - } - - /** - * This test spawns a Service in a new process to check the initial state of - * SecureRandom. It then attempts to make the PID number wrap around so it - * sees a new process with the same PID twice. The test completes when it - * sees two newly started processes with the same PID and compares their - * output. - */ - @TimeoutReq(minutes=15) - public void testCheckForDuplicateOutput() throws Exception { - assertEquals("Only supports up to " + MAX_PID + " because of memory requirements", - Integer.toString(MAX_PID), getFirstLineFromFile("/proc/sys/kernel/pid_max")); - - final String packageName = getContext().getPackageName(); - String separateProcessName = packageName + SEPARATE_PROCESS_NAME; - - /* - * Using a byte[][] and BitSet gives us a fixed upper bound for the - * memory cost of this test. One could possibly use a SparseArray if the - * upper bound becomes too large (for instance, if PID_MAX is large), - * only keep track of a smaller number of outputs, and just cause a - * wrap-around of PIDs to keep the test working. - */ - byte[][] outputs = new byte[MAX_PID][RANDOM_BYTES_PER_PID]; - BitSet seenPids = new BitSet(MAX_PID); - - ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); - - int myPid = android.os.Process.myPid(); - - /* - * We're guaranteed to see at least one duplicate if we iterate MAX_PID - * number of times because of the pigeonhole principle. In an attempt to - * hit a collision faster, first get a closely-spaced sampling of PIDs - * then spin up a bunch of threads locally to get us closer to wrapping - * around to the first PID. - */ - int firstPid = -1; - int previousPid = -1; - int lastPid = -1; - for (int i = 0; i < MAX_PID; i++) { - byte[] output = new byte[RANDOM_BYTES_PER_PID]; - int pid; - - mLatch = new CountDownLatch(1); - getContext().startService(mSeparateIntent); - getContext().bindService(mSeparateIntent, mServiceConnection, 0); - if (!mLatch.await(ANSWER_TIMEOUT_SECONDS, TimeUnit.SECONDS)) { - fail("Timeout waiting for answer from SecureRandomService; cannot complete test"); - } - - // Create another latch we'll use to ensure the service has stopped. - final CountDownLatch serviceStopLatch = new CountDownLatch(1); - mSecureRandomService.asBinder().linkToDeath(new IBinder.DeathRecipient() { - @Override - public void binderDied() { - serviceStopLatch.countDown(); - } - }, 0); - - try { - pid = mSecureRandomService.getRandomBytesAndPid(output); - } catch (RemoteException e) { - // The process died before we could query. Try again. - continue; - } - - getContext().unbindService(mServiceConnection); - - /* - * Ensure the background process has stopped by waiting for the - * latch to fire. - */ - int tries = 0; - do { - /* - * If this has looped more than once, try to yield to - * system_server. - */ - if (tries > 0) { - Thread.yield(); - } - getContext().stopService(mSeparateIntent); - am.killBackgroundProcesses(packageName); - } while (!serviceStopLatch.await(100, TimeUnit.MILLISECONDS) && tries++ < MAX_SHUTDOWN_TRIES); - assertTrue("Background process should have stopped already", tries < MAX_SHUTDOWN_TRIES); - - /* - * Make sure the AndroidManifest.xml wasn't altered in a way that - * breaks the test. - */ - assertFalse("SecureRandomService must run in a different process. Check " - + "AndroidManifest.xml to ensure it has a unique android:process=\"...\"", - myPid == pid); - - // We didn't get a new process for some reason. Try again. - if (previousPid == pid) { - i--; - continue; - } else if (previousPid == -1 && firstPid == -1) { - /* - * The first time around, we'll discard the output. This is - * needed because we don't know if the SecureRandomService instance - * has been running before or not. To be consistent, we only - * want the first outputs from SecureRandom for this test. - */ - i--; - previousPid = pid; - continue; - } else { - previousPid = pid; - } - - if (seenPids.get(pid)) { - assertFalse("SecureRandom should not output the same value twice (pid=" + pid - + ", output=" + Arrays.toString(output) + ", outputs[pid]=" - + Arrays.toString(outputs[pid]) + ")", - Arrays.equals(output, outputs[pid])); - return; - } - - seenPids.set(pid); - System.arraycopy(output, 0, outputs[pid], 0, output.length); - - if (firstPid == -1) { - firstPid = pid; - } - - if (i <= PRIMING_ITERATIONS) { - lastPid = pid; - } else if (pid > lastPid && (lastPid > firstPid || pid < firstPid)) { - wastePids(firstPid, previousPid); - } - } - - /* - * This should never be reached unless the test was altered to break it. - * Since we're looping until we see PID_MAX unique answers, we must have - * seen a duplicate by the pigeonhole principle. - */ - fail("Must see a duplicate PID"); - } - - /** - * This is an attempt to get the PIDs to roll over faster. Threads use up - * PIDs on Android and spawning a new thread is much faster than having - * another service spawned as we are doing in this test. - */ - private static void wastePids(int firstPid, int previousPid) { - int distance = (firstPid - previousPid + MAX_PID) % MAX_PID; - - // Don't waste PIDs if we're close to wrap-around to improve odds of - // collision. - if ((distance < PID_WASTING_SKIP_LOWER) || (MAX_PID - distance < PID_WASTING_SKIP_UPPER)) { - return; - } - - for (int i = 0; i < distance; i++) { - Thread t = new Thread(); - t.start(); - } - } - - private static String getFirstLineFromFile(String filename) throws IOException { - BufferedReader in = null; - try { - in = new BufferedReader(new FileReader(filename)); - final String line = in.readLine(); - if (line == null) { - throw new EOFException("EOF encountered before reading first line of " + filename); - } - return line.trim(); - } finally { - if (in != null) { - in.close(); - } - } - } -} |