Added Media Codec Test methods
Bug: 72322539
Test: manual build
Change-Id: Ib090f9210ef88bc346681ba3df5c1c236915e21e
Merged-In: I52f9dda8e783592a0cc0dafbdd0368b10c12dcf0
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index cdbc1d6..ecd0b6f 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -37,6 +37,12 @@
<option name="push" value="CVE-2016-8434->/data/local/tmp/CVE-2016-8434" />
<option name="push" value="CVE-2016-2504->/data/local/tmp/CVE-2016-2504" />
+ <!-- Media Codec Tests -->
+ <!-- Please add tests for media codecs below to avoid merge conflict -->
+ <option name="push" value="testhevcdec->/data/local/tmp/testhevcdec" />
+ <option name="push" value="testavcdec->/data/local/tmp/testavcdec" />
+ <option name="push" value="testmpeg2dec->/data/local/tmp/testmpeg2dec" />
+
<!-- Bulletin 2015-12 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
<option name="push" value="CVE-2015-6626->/data/local/tmp/CVE-2015-6626" />
diff --git a/hostsidetests/securitybulletin/securityPatch/avcdec/Android.mk b/hostsidetests/securitybulletin/securityPatch/avcdec/Android.mk
new file mode 100644
index 0000000..563edf2a
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/avcdec/Android.mk
@@ -0,0 +1,40 @@
+# Copyright (C) 2018 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.
+#=========================================================================
+# NOTE: This module uses the libavc's testbench from external folder
+# without creating a copy of the testbench locally. Hence LOCAL_SRC_FILES
+# is pointed to external folder.
+# This module is dependent on external/libavc/test
+#=========================================================================
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := testavcdec
+LOCAL_SRC_FILES := ../../../../../external/libavc/test/decoder/main.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+LOCAL_C_INCLUDES := external/libavc/common
+LOCAL_C_INCLUDES += external/libavc/decoder
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_SHARED_LIBRARIES += libstagefright_soft_avcdec
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS += -Wall -Werror
+LOCAL_CFLAGS += -DPROFILE_ENABLE -fPIC -DMD5_DISABLE
+include $(BUILD_CTS_EXECUTABLE)
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/securityPatch/hevcdec/Android.mk b/hostsidetests/securitybulletin/securityPatch/hevcdec/Android.mk
new file mode 100644
index 0000000..3d069fa
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/hevcdec/Android.mk
@@ -0,0 +1,42 @@
+# Copyright (C) 2018 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.
+
+#=========================================================================
+# NOTE: This module uses the libhevc's testbench from external folder
+# without creating a copy of the testbench locally. Hence LOCAL_SRC_FILES
+# is pointed to external folder.
+# This module is dependent on external/libhevc/test
+#=========================================================================
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := testhevcdec
+LOCAL_SRC_FILES := ../../../../../external/libhevc/test/decoder/main.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+LOCAL_C_INCLUDES := external/libhevc/common
+LOCAL_C_INCLUDES += external/libhevc/decoder
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_SHARED_LIBRARIES += libstagefright_soft_hevcdec
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS += -Wall -Werror
+LOCAL_CFLAGS += -DPROFILE_ENABLE -fPIC -DMD5_DISABLE
+include $(BUILD_CTS_EXECUTABLE)
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/securityPatch/mpeg2dec/Android.mk b/hostsidetests/securitybulletin/securityPatch/mpeg2dec/Android.mk
new file mode 100644
index 0000000..f71b2fa
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/mpeg2dec/Android.mk
@@ -0,0 +1,42 @@
+# Copyright (C) 2018 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.
+
+#=========================================================================
+# NOTE: This module uses the libmpeg2's testbench from external folder
+# without creating a copy of the testbench locally. Hence LOCAL_SRC_FILES
+# is pointed to external folder.
+# This module is dependent on external/libmpeg2/test
+#=========================================================================
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := testmpeg2dec
+LOCAL_SRC_FILES := ../../../../../external/libmpeg2/test/decoder/main.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+LOCAL_C_INCLUDES := external/libmpeg2/common
+LOCAL_C_INCLUDES += external/libmpeg2/decoder
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_SHARED_LIBRARIES += libstagefright_soft_mpeg2dec
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS += -Wall -Werror
+LOCAL_CFLAGS += -DPROFILE_ENABLE -fPIC -DMD5_DISABLE
+include $(BUILD_CTS_EXECUTABLE)
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
index b9f3b2b..f834c38 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
@@ -30,7 +30,10 @@
import java.util.concurrent.TimeUnit;
import java.util.Scanner;
+import java.util.regex.Pattern;
+import java.lang.Thread;
import static org.junit.Assert.*;
+import junit.framework.Assert;
public class AdbUtils {
@@ -47,7 +50,7 @@
/**
* Pushes and runs a binary to the selected device
*
- * @param pathToPoc a string path to poc from the /res folder
+ * @param pocName name of the poc binary
* @param device device to be ran on
* @return the console output from the binary
*/
@@ -59,15 +62,35 @@
/**
* Pushes and runs a binary to the selected device
*
- * @param pocName a string path to poc from the /res folder
+ * @param pocName name of the poc binary
* @param device device to be ran on
* @param timeout time to wait for output in seconds
* @return the console output from the binary
*/
public static String runPoc(String pocName, ITestDevice device, int timeout) throws Exception {
+ return runPoc(pocName, device, timeout, null);
+ }
+
+ /**
+ * Pushes and runs a binary to the selected device
+ *
+ * @param pocName name of the poc binary
+ * @param device device to be ran on
+ * @param timeout time to wait for output in seconds
+ * @param arguments the input arguments for the poc
+ * @return the console output from the binary
+ */
+ public static String runPoc(String pocName, ITestDevice device, int timeout, String arguments)
+ throws Exception {
device.executeShellCommand("chmod +x /data/local/tmp/" + pocName);
CollectingOutputReceiver receiver = new CollectingOutputReceiver();
- device.executeShellCommand("/data/local/tmp/" + pocName, receiver, timeout, TimeUnit.SECONDS, 0);
+ if (arguments != null) {
+ device.executeShellCommand("/data/local/tmp/" + pocName + " " + arguments, receiver,
+ timeout, TimeUnit.SECONDS, 0);
+ } else {
+ device.executeShellCommand("/data/local/tmp/" + pocName, receiver, timeout,
+ TimeUnit.SECONDS, 0);
+ }
String output = receiver.getOutput();
return output;
}
@@ -75,16 +98,35 @@
/**
* Pushes and runs a binary to the selected device and ignores any of its output.
*
- * @param pocName a string path to poc from the /res folder
+ * @param pocName name of the poc binary
* @param device device to be ran on
* @param timeout time to wait for output in seconds
*/
public static void runPocNoOutput(String pocName, ITestDevice device, int timeout)
throws Exception {
+ runPocNoOutput(pocName, device, timeout, null);
+ }
+
+ /**
+ * Pushes and runs a binary with arguments to the selected device and
+ * ignores any of its output.
+ *
+ * @param pocName name of the poc binary
+ * @param device device to be ran on
+ * @param timeout time to wait for output in seconds
+ * @param arguments input arguments for the poc
+ */
+ public static void runPocNoOutput(String pocName, ITestDevice device, int timeout,
+ String arguments) throws Exception {
device.executeShellCommand("chmod +x /data/local/tmp/" + pocName);
NullOutputReceiver receiver = new NullOutputReceiver();
- device.executeShellCommand("/data/local/tmp/" + pocName, receiver, timeout,
- TimeUnit.SECONDS, 0);
+ if (arguments != null) {
+ device.executeShellCommand("/data/local/tmp/" + pocName + " " + arguments, receiver,
+ timeout, TimeUnit.SECONDS, 0);
+ } else {
+ device.executeShellCommand("/data/local/tmp/" + pocName, receiver, timeout,
+ TimeUnit.SECONDS, 0);
+ }
}
/**
@@ -238,4 +280,54 @@
assertTrue("PoC returned exit status 113: vulnerable",
runPocGetExitStatus(pocName, device, timeout) != 113);
}
+
+ /**
+ * Executes a given poc within a given timeout. Returns error if the
+ * given poc doesnt complete its execution within timeout. It also deletes
+ * the list of files provided.
+ *
+ * @param runner the thread which will be run
+ * @param timeout the timeout within which the thread's execution should
+ * complete
+ * @param device device to be ran on
+ * @param inputFiles list of files to be deleted
+ */
+ public static void runWithTimeoutDeleteFiles(Runnable runner, int timeout, ITestDevice device,
+ String[] inputFiles) throws Exception {
+ Thread t = new Thread(runner);
+ t.start();
+ boolean test_failed = false;
+ try {
+ t.join(timeout);
+ } catch (InterruptedException e) {
+ test_failed = true;
+ } finally {
+ if (inputFiles != null) {
+ for (int i = 0; i < inputFiles.length; i++) {
+ AdbUtils.runCommandLine("rm /data/local/tmp/" + inputFiles[i], device);
+ }
+ }
+ if (test_failed == true) {
+ Assert.fail("PoC was interrupted");
+ }
+ }
+ if (t.isAlive()) {
+ Assert.fail("PoC not completed within timeout of " + timeout + " ms");
+ }
+ }
+
+ /**
+ * Raises assert exception upon crash/error occurence
+ *
+ * @param crashPatternList array of crash log patterns to be checked for
+ * @param logcat String to be parsed
+ */
+ public static void checkCrash(String crashPatternList[], String logcat)
+ throws Exception {
+ for (int i = 0; i < crashPatternList.length; i++) {
+ assertFalse("Crash log pattern found!",
+ Pattern.compile(crashPatternList[i],
+ Pattern.MULTILINE).matcher(logcat).find());
+ }
+ }
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestMediaCodec.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMediaCodec.java
new file mode 100644
index 0000000..179cf24
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMediaCodec.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2018 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 com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import android.platform.test.annotations.SecurityTest;
+import java.util.regex.Pattern;
+
+@SecurityTest
+public class TestMediaCodec extends SecurityTestCase {
+
+ final static int TIMEOUT_SEC = 9 * 60;
+ final static String RESOURCE_ROOT = "/";
+ final static String TMP_FILE_PATH = "/data/local/tmp/";
+ final static String HEVCDEC_BINARY = "testhevcdec";
+ final static String AVCDEC_BINARY = "testavcdec";
+ final static String MPEG2DEC_BINARY = "testmpeg2dec";
+
+ /***********************************************************
+ To prevent merge conflicts, add HEVC decoder tests for N
+ below this comment, before any existing test methods
+ ***********************************************************/
+
+
+ /***********************************************************
+ To prevent merge conflicts, add HEVC decoder tests for O
+ below this comment, before any existing test methods
+ ***********************************************************/
+
+
+ /***********************************************************
+ To prevent merge conflicts, add AVC decoder tests for N
+ below this comment, before any existing test methods
+ ***********************************************************/
+
+
+ /***********************************************************
+ To prevent merge conflicts, add AVC decoder tests for O
+ below this comment, before any existing test methods
+ ***********************************************************/
+
+
+ /***********************************************************
+ To prevent merge conflicts, add MPEG2 decoder tests for N
+ below this comment, before any existing test methods
+ ***********************************************************/
+
+
+ /***********************************************************
+ To prevent merge conflicts, add MPEG2 decoder tests for O
+ below this comment, before any existing test methods
+ ***********************************************************/
+
+
+ /**
+ * Calls runDecodeTest with HEVC decoder binary name as argument
+ *
+ * @param inputFiles files required as input
+ * @param arguments arguments for running the binary
+ * @param device device to be run on
+ * @param errPattern error patterns to be checked for
+ */
+ public static void runHevcDecodeTest(String inputFiles[], String arguments,
+ ITestDevice device, String errPattern[]) throws Exception {
+ runDecodeTest(HEVCDEC_BINARY, inputFiles, arguments, device, errPattern);
+ }
+
+ /**
+ * Calls runDecodeTest with MPEG2 decoder binary name as argument
+ *
+ * @param inputFiles files required as input
+ * @param arguments arguments for running the binary
+ * @param device device to be run on
+ * @param errPattern error patterns to be checked for
+ */
+ public static void runMpeg2DecodeTest(String inputFiles[], String arguments,
+ ITestDevice device, String errPattern[]) throws Exception {
+ runDecodeTest(MPEG2DEC_BINARY, inputFiles, arguments, device, errPattern);
+ }
+
+ /**
+ * Calls runDecodeTest with AVC decoder binary name as argument
+ *
+ * @param inputFiles files required as input
+ * @param arguments arguments for running the binary
+ * @param device device to be run on
+ * @param errPattern error patterns to be checked for
+ */
+ public static void runAvcDecodeTest(String inputFiles[], String arguments,
+ ITestDevice device, String errPattern[]) throws Exception {
+ runDecodeTest(AVCDEC_BINARY, inputFiles, arguments, device, errPattern);
+ }
+
+ /**
+ * Checks for linker errors
+ *
+ * @param binaryName name of the decoder binary
+ * @param logcat String to be parsed
+ */
+ public static boolean isLinkerErrorPresent(String binaryName, String logcat)
+ throws Exception {
+ return Pattern.compile(".*CANNOT LINK EXECUTABLE \""
+ + TMP_FILE_PATH + binaryName + "\".*",
+ Pattern.MULTILINE).matcher(logcat).find();
+ }
+
+ /**
+ * Checks for codec crash
+ *
+ * @param binaryName Name of the decoder binary
+ * @param errPattern error patterns to be checked for
+ * @param logcat String to be parsed
+ */
+ public static void checkCodecCrash(String binaryName, String errPattern[],
+ String logcat) throws Exception {
+ String genericCrashPattern[] = {
+ ".*name: " + binaryName + " >>> " + TMP_FILE_PATH + binaryName
+ + " <<<.*SIGABRT.*",
+ ".*name: " + binaryName + " >>> " + TMP_FILE_PATH + binaryName
+ + " <<<.*SIGSEGV.*"};
+ AdbUtils.checkCrash(genericCrashPattern, logcat);
+ if (errPattern != null) {
+ AdbUtils.checkCrash(errPattern, logcat);
+ }
+ }
+
+ /**
+ * Pushes input files, runs the PoC and checks for crash and hang
+ *
+ * @param binaryName name of the decoder binary
+ * @param inputFiles files required as input
+ * @param arguments arguments for running the binary
+ * @param device device to be run on
+ * @param errPattern error patterns to be checked for
+ */
+ public static void runDecodeTest(String binaryName, String inputFiles[],
+ String arguments, ITestDevice device, String errPattern[])
+ throws Exception {
+ if (inputFiles != null) {
+ for (int i = 0; i < inputFiles.length; i++) {
+ AdbUtils.pushResource(RESOURCE_ROOT + inputFiles[i],
+ TMP_FILE_PATH + inputFiles[i], device);
+ }
+ }
+ AdbUtils.runCommandLine("logcat -c", device);
+ AdbUtils.runWithTimeoutDeleteFiles(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ AdbUtils.runPocNoOutput(binaryName, device,
+ TIMEOUT_SEC + 30, arguments);
+ } catch (Exception e) {
+ CLog.w("Exception: " + e.getMessage());
+ }
+ }
+ }, TIMEOUT_SEC * 1000, device, inputFiles);
+ String logcatOut = AdbUtils.runCommandLine("logcat -d", device);
+ boolean linkerErrorFound = isLinkerErrorPresent(binaryName, logcatOut);
+ if (linkerErrorFound != true) {
+ checkCodecCrash(binaryName, errPattern, logcatOut);
+ }
+ }
+}
\ No newline at end of file