Fix STS test for CVE-2021-0399
Use android callbacks and intents to get results from other activities
Bug: 175817167
Test: sts-tradefed run sts-engbuild-no-spl-lock -m CtsSecurityTestCases -t android.security.cts.CVE_2021_0339
Change-Id: If277bee63cf06d6c2dae5e54d946830af115dc84
Merged-In: If277bee63cf06d6c2dae5e54d946830af115dc84
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0339.java b/tests/tests/security/src/android/security/cts/CVE_2021_0339.java
index 5ace5df..a59d749 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2021_0339.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0339.java
@@ -17,98 +17,126 @@
package android.security.cts;
import static org.junit.Assert.assertThat;
-import static org.hamcrest.Matchers.lessThan;
+import static org.junit.Assume.assumeThat;
+import static org.hamcrest.Matchers.*;
-import android.test.AndroidTestCase;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
-import android.platform.test.annotations.SecurityTest;
+import android.os.Bundle;
+import android.os.RemoteCallback;
import android.os.SystemClock;
+import android.platform.test.annotations.SecurityTest;
+import android.test.AndroidTestCase;
+import android.util.Log;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
-import android.util.Log;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
@SecurityTest
@RunWith(AndroidJUnit4.class)
public class CVE_2021_0339 {
static final String TAG = CVE_2021_0339.class.getSimpleName();
private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts";
+ private static final String CALLBACK_KEY = "testactivitycallback";
+ private static final String RESULT_KEY = "testactivityresult";
+ static final int DURATION_RESULT_CODE = 1;
static final int MAX_TRANSITION_DURATION_MS = 3000; // internal max
static final int TIME_MEASUREMENT_DELAY_MS = 5000; // tolerance for lag.
- public static boolean testCompleted;
- public FirstActivity fActivity;
- public SecondActivity sActivity;
-
- private void launchActivity(Class<? extends Activity> clazz) {
+ private void launchActivity(Class<? extends Activity> clazz, RemoteCallback cb) {
final Context context = InstrumentationRegistry.getInstrumentation().getContext();
final Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName(SECURITY_CTS_PACKAGE_NAME, clazz.getName());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(CALLBACK_KEY, cb);
context.startActivity(intent);
}
/**
* b/175817167
+ * start the first activity and get the result from the remote callback
*/
@Test
@SecurityTest
public void testPocCVE_2021_0339() throws Exception {
+ CompletableFuture<Integer> callbackReturn = new CompletableFuture<>();
+ RemoteCallback cb = new RemoteCallback((Bundle result) ->
+ callbackReturn.complete(result.getInt(RESULT_KEY)));
+ launchActivity(FirstActivity.class, cb); // start activity with callback as intent extra
- Log.d(TAG, "test start");
- testCompleted = false;
- launchActivity(FirstActivity.class);
+ // blocking while the remotecallback is unset
+ int duration = callbackReturn.get(15, TimeUnit.SECONDS);
- //wait for SecondActivity animation to complete
- synchronized(CVE_2021_0339.class){
- if(!testCompleted)
- CVE_2021_0339.class.wait();
- }
- Log.d(TAG, "test completed");
+ // if we couldn't get the duration of secondactivity in firstactivity, the default is -1
+ assumeThat(duration, not(equals(-1)));
- //A duration of a transition from "FirstActivity" to "Second Activity"
- //is set in this test to 10 seconds
- // (res/anim/translate1.xml and res/anim/translate2.xml)
- //The fix is supposed to limit the duration to 3000 ms.
- // testing for > 8s
- assertThat(SecondActivity.duration,
- lessThan(MAX_TRANSITION_DURATION_MS + TIME_MEASUREMENT_DELAY_MS));
+ // the max duration after the fix is 3 seconds.
+ // we check to see that the total duration was less than 8 seconds after accounting for lag
+ assertThat(duration,
+ lessThan(MAX_TRANSITION_DURATION_MS + TIME_MEASUREMENT_DELAY_MS));
}
+ /**
+ * create an activity so that the second activity has something to animate from
+ * start the second activity and get the result
+ * return the result from the second activity in the remotecallback
+ */
public static class FirstActivity extends Activity {
+ private RemoteCallback cb;
- @Override
- public void onEnterAnimationComplete() {
- super.onEnterAnimationComplete();
- Intent intent = new Intent(this, SecondActivity.class);
- intent.putExtra("STARTED_TIMESTAMP", SystemClock.uptimeMillis());
- startActivity(intent);
- overridePendingTransition(R.anim.translate2,R.anim.translate1);
- Log.d(TAG,this.getLocalClassName()+" onEnterAnimationComplete()");
- }
+ @Override
+ public void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+ cb = (RemoteCallback) getIntent().getExtras().get(CALLBACK_KEY);
+ }
+
+ @Override
+ public void onEnterAnimationComplete() {
+ super.onEnterAnimationComplete();
+ Intent intent = new Intent(this, SecondActivity.class);
+ intent.putExtra("STARTED_TIMESTAMP", SystemClock.uptimeMillis());
+ startActivityForResult(intent, DURATION_RESULT_CODE);
+ overridePendingTransition(R.anim.translate2,R.anim.translate1);
+ Log.d(TAG,this.getLocalClassName()+" onEnterAnimationComplete()");
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode,int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == DURATION_RESULT_CODE && resultCode == RESULT_OK) {
+ // this is the result that we requested
+ int duration = data.getIntExtra("duration", -1); // get result from secondactivity
+ Bundle res = new Bundle();
+ res.putInt(RESULT_KEY, duration);
+ finish();
+ cb.sendResult(res); // update callback in test
+ }
+ }
}
+ /**
+ * measure time since secondactivity start to secondactivity animation complete
+ * return the duration in the result
+ */
public static class SecondActivity extends Activity{
- public static int duration = 0;
-
- @Override
- public void onEnterAnimationComplete() {
- super.onEnterAnimationComplete();
- long completedTs = SystemClock.uptimeMillis();
- long startedTs = getIntent().getLongExtra("STARTED_TIMESTAMP", 0);
- duration = (int)(completedTs - startedTs);
- Log.d(TAG, this.getLocalClassName()
- + " onEnterAnimationComplete() duration=" + Long.toString(duration));
-
- //Notify main thread that the test is completed
- synchronized(CVE_2021_0339.class){
- CVE_2021_0339.testCompleted = true;
- CVE_2021_0339.class.notifyAll();
+ @Override
+ public void onEnterAnimationComplete() {
+ super.onEnterAnimationComplete();
+ long completedTs = SystemClock.uptimeMillis();
+ long startedTs = getIntent().getLongExtra("STARTED_TIMESTAMP", 0);
+ int duration = (int)(completedTs - startedTs);
+ Log.d(TAG, this.getLocalClassName()
+ + " onEnterAnimationComplete() duration=" + Long.toString(duration));
+ Intent durationIntent = new Intent();
+ durationIntent.putExtra("duration", duration);
+ setResult(RESULT_OK, durationIntent); // set result for firstactivity
+ finish(); // firstactivity only gets the result when we finish
}
- }
}
}