summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2018-11-20 19:35:42 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-11-20 19:35:42 +0000
commit6d549abdf13666dee95cf9ee1d22ea5501aa0486 (patch)
tree74eea765bc16a22fac92f7d31b7b050efabf106f
parenta46868fca645ed193ec15c6790ccb970dd81d495 (diff)
parent36ac203ccee730c89e7cd4dfa46ad4455719c19b (diff)
downloadcts-6d549abdf13666dee95cf9ee1d22ea5501aa0486.tar.gz
Merge "DO NOT MERGE: Remove ClonedSecureRandomTest" into marshmallow-cts-dev
-rw-r--r--tests/tests/security/src/android/security/cts/ClonedSecureRandomTest.java266
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();
- }
- }
- }
-}