CTS test for Android Security CVE-2019-2129
Test: cts-tradefed run cts -m CtsSecurityTestCases -t
android.security.cts.StagefrightTest#test_android_CVE_2019_2129
Bug: 135207745
Bug: 124781927
Change-Id: I9f81abe560bc05a505756f004d7548d5fc482a61
diff --git a/tests/tests/security/res/raw/cve_2019_2129.3gp b/tests/tests/security/res/raw/cve_2019_2129.3gp
new file mode 100644
index 0000000..c461081
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2129.3gp
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index 64707eb..ba75596 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -78,6 +78,7 @@
import android.security.cts.R;
import android.security.NetworkSecurityPolicy;
+import android.media.TimedText;
/**
* Verify that the device is not vulnerable to any known Stagefright
@@ -1388,6 +1389,80 @@
t.join(); // wait for thread to exit so we're sure the player was released
}
+ /*
+ * b/135207745
+ */
+ @SecurityTest(minPatchLevel = "2019-08")
+ public void testStagefright_cve_2019_2129() throws Exception {
+ final int rid = R.raw.cve_2019_2129;
+ String name = getInstrumentation().getContext().getResources().getResourceEntryName(rid);
+ Log.i(TAG, "start mediaplayer test for: " + name);
+
+ final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener() {
+ @Override
+ public void onPrepared(MediaPlayer mp) {
+ super.onPrepared(mp);
+ mp.setLooping(true);
+ }
+ };
+
+ LooperThread t = new LooperThread(new Runnable() {
+ @Override
+ public void run() {
+ MediaPlayer mp = new MediaPlayer();
+ mp.setOnErrorListener(mpcl);
+ mp.setOnPreparedListener(mpcl);
+ mp.setOnCompletionListener(mpcl);
+ RenderTarget renderTarget = RenderTarget.create();
+ Surface surface = renderTarget.getSurface();
+ mp.setSurface(surface);
+ AssetFileDescriptor fd = null;
+ try {
+ fd = getInstrumentation().getContext().getResources().openRawResourceFd(rid);
+ mp.setOnTimedTextListener(new MediaPlayer.OnTimedTextListener() {
+ @Override
+ public void onTimedText(MediaPlayer p, TimedText text) {
+ if (text != null) {
+ Log.d(TAG, "text = " + text.getText());
+ }
+ }
+ });
+ mp.setDataSource(fd.getFileDescriptor(),
+ fd.getStartOffset(),
+ fd.getLength());
+ // keep the original as in poc by not using prepareAsync
+ mp.prepare();
+ mp.selectTrack(2);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception is caught " + e.getMessage());
+ e.printStackTrace();
+ } finally {
+ closeQuietly(fd);
+ }
+
+ try {
+ // here to catch & swallow the runtime crash in exception
+ // after the place where original poc failed in
+ // java.lang.IllegalArgumentException: parseParcel()
+ // which is beyond test control.
+ Looper.loop();
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Exception is caught on Looper.loop() " + e.getMessage());
+ e.printStackTrace();
+ }
+ mp.release();
+ renderTarget.destroy();
+ }
+ });
+
+ t.start();
+ String cve = name.replace("_", "-").toUpperCase();
+ assertFalse("Device *IS* vulnerable to " + cve,
+ mpcl.waitForError() == MediaPlayer.MEDIA_ERROR_SERVER_DIED);
+ t.stopLooper();
+ t.join(); // wait for thread to exit so we're sure the player was released
+ }
+
private void doStagefrightTestMediaCodec(final int rid) throws Exception {
doStagefrightTestMediaCodec(rid, null);
}