diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2020-09-09 23:05:36 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2020-09-09 23:05:36 +0000 |
commit | dd985e32f215fb92e7ca174cbe9fd8a73343e414 (patch) | |
tree | 4de346de9d4c331b798c8c1954df2db22a63b3a0 | |
parent | b867f2c12982ef1602906ec93c53de3a740a8722 (diff) | |
parent | bbe9ff0ed9a1481985d1481ac3e19fa4fa5d9921 (diff) | |
download | native-dd985e32f215fb92e7ca174cbe9fd8a73343e414.tar.gz |
Snap for 6823548 from bbe9ff0ed9a1481985d1481ac3e19fa4fa5d9921 to rvc-qpr1-release
Change-Id: I16fe3485403080d9447d74606a3e27ca8ce914a3
-rw-r--r-- | libs/binder/IPCThreadState.cpp | 24 | ||||
-rw-r--r-- | libs/binder/include/binder/IPCThreadState.h | 17 | ||||
-rw-r--r-- | libs/binder/include/private/binder/binder_module.h | 31 | ||||
-rw-r--r-- | libs/binder/tests/binderLibTest.cpp | 43 | ||||
-rw-r--r-- | services/sensorservice/SensorEventConnection.cpp | 18 | ||||
-rw-r--r-- | services/sensorservice/SensorService.cpp | 9 | ||||
-rw-r--r-- | services/sensorservice/SensorService.h | 1 |
7 files changed, 140 insertions, 3 deletions
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index d67ce15ca9..7d008e25ad 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -860,6 +860,10 @@ status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) err = FAILED_TRANSACTION; goto finish; + case BR_FROZEN_REPLY: + err = FAILED_TRANSACTION; + goto finish; + case BR_ACQUIRE_RESULT: { ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT"); @@ -1316,6 +1320,26 @@ void IPCThreadState::threadDestructor(void *st) } } +status_t IPCThreadState::freeze(pid_t pid, bool enable, uint32_t timeout_ms) { + struct binder_freeze_info info; + int ret = 0; + + info.pid = pid; + info.enable = enable; + info.timeout_ms = timeout_ms; + + +#if defined(__ANDROID__) + if (ioctl(self()->mProcess->mDriverFD, BINDER_FREEZE, &info) < 0) + ret = -errno; +#endif + + // + // ret==-EAGAIN indicates that transactions have not drained. + // Call again to poll for completion. + // + return ret; +} void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, size_t /*dataSize*/, diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h index 4818889436..7024f27cc7 100644 --- a/libs/binder/include/binder/IPCThreadState.h +++ b/libs/binder/include/binder/IPCThreadState.h @@ -34,7 +34,22 @@ class IPCThreadState public: static IPCThreadState* self(); static IPCThreadState* selfOrNull(); // self(), but won't instantiate - + + // Freeze or unfreeze the binder interface to a specific process. When freezing, this method + // will block up to timeout_ms to process pending transactions directed to pid. Unfreeze + // is immediate. Transactions to processes frozen via this method won't be delivered and the + // driver will return BR_FROZEN_REPLY to the client sending them. After unfreeze, + // transactions will be delivered normally. + // + // pid: id for the process for which the binder interface is to be frozen + // enable: freeze (true) or unfreeze (false) + // timeout_ms: maximum time this function is allowed to block the caller waiting for pending + // binder transactions to be processed. + // + // returns: 0 in case of success, a value < 0 in case of error + __attribute__((weak)) + static status_t freeze(pid_t pid, bool enabled, uint32_t timeout_ms); + sp<ProcessState> process(); status_t clearLastError(); diff --git a/libs/binder/include/private/binder/binder_module.h b/libs/binder/include/private/binder/binder_module.h index c22be9f786..7898928f9f 100644 --- a/libs/binder/include/private/binder/binder_module.h +++ b/libs/binder/include/private/binder/binder_module.h @@ -36,6 +36,37 @@ namespace android { #include <sys/ioctl.h> #include <linux/android/binder.h> +#ifndef BR_FROZEN_REPLY +// Temporary definition of BR_FROZEN_REPLY. For production +// this will come from UAPI binder.h +#define BR_FROZEN_REPLY _IO('r', 18) +#endif //BR_FROZEN_REPLY + +#ifndef BINDER_FREEZE +/* + * Temporary definitions for freeze support. For the final version + * these will be defined in the UAPI binder.h file from upstream kernel. + */ +#define BINDER_FREEZE _IOW('b', 14, struct binder_freeze_info) + +struct binder_freeze_info { + // + // Group-leader PID of process to be frozen + // + uint32_t pid; + // + // Enable(1) / Disable(0) freeze for given PID + // + uint32_t enable; + // + // Timeout to wait for transactions to drain. + // 0: don't wait (ioctl will return EAGAIN if not drained) + // N: number of ms to wait + uint32_t timeout_ms; +}; +#endif //BINDER_FREEZE + + #ifdef __cplusplus } // namespace android #endif diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp index 917751ef34..145c09940b 100644 --- a/libs/binder/tests/binderLibTest.cpp +++ b/libs/binder/tests/binderLibTest.cpp @@ -16,6 +16,7 @@ #include <errno.h> #include <fcntl.h> +#include <fstream> #include <poll.h> #include <pthread.h> #include <stdio.h> @@ -79,6 +80,8 @@ enum BinderLibTestTranscationCode { BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION, BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, BINDER_LIB_TEST_GET_SCHEDULING_POLICY, + BINDER_LIB_TEST_NOP_TRANSACTION_WAIT, + BINDER_LIB_TEST_GETPID, BINDER_LIB_TEST_ECHO_VECTOR, BINDER_LIB_TEST_REJECT_BUF, }; @@ -399,6 +402,40 @@ TEST_F(BinderLibTest, NopTransaction) { EXPECT_EQ(NO_ERROR, ret); } +TEST_F(BinderLibTest, Freeze) { + status_t ret; + Parcel data, reply, replypid; + std::ifstream freezer_file("/sys/fs/cgroup/freezer/cgroup.freeze"); + + //Pass test on devices where the freezer is not supported + if (freezer_file.fail()) { + GTEST_SKIP(); + return; + } + + std::string freezer_enabled; + std::getline(freezer_file, freezer_enabled); + + //Pass test on devices where the freezer is disabled + if (freezer_enabled != "1") { + GTEST_SKIP(); + return; + } + + ret = m_server->transact(BINDER_LIB_TEST_GETPID, data, &replypid); + int32_t pid = replypid.readInt32(); + EXPECT_EQ(NO_ERROR, ret); + for (int i = 0; i < 10; i++) { + EXPECT_EQ(NO_ERROR, m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION_WAIT, data, &reply, TF_ONE_WAY)); + } + EXPECT_EQ(-EAGAIN, IPCThreadState::self()->freeze(pid, 1, 0)); + EXPECT_EQ(-EAGAIN, IPCThreadState::self()->freeze(pid, 1, 0)); + EXPECT_EQ(NO_ERROR, IPCThreadState::self()->freeze(pid, 1, 1000)); + EXPECT_EQ(FAILED_TRANSACTION, m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply)); + EXPECT_EQ(NO_ERROR, IPCThreadState::self()->freeze(pid, 0, 0)); + EXPECT_EQ(NO_ERROR, m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply)); +} + TEST_F(BinderLibTest, SetError) { int32_t testValue[] = { 0, -123, 123 }; for (size_t i = 0; i < ARRAY_SIZE(testValue); i++) { @@ -1178,6 +1215,12 @@ class BinderLibTestService : public BBinder pthread_mutex_unlock(&m_serverWaitMutex); return ret; } + case BINDER_LIB_TEST_GETPID: + reply->writeInt32(getpid()); + return NO_ERROR; + case BINDER_LIB_TEST_NOP_TRANSACTION_WAIT: + usleep(5000); + return NO_ERROR; case BINDER_LIB_TEST_NOP_TRANSACTION: return NO_ERROR; case BINDER_LIB_TEST_DELAYED_CALL_BACK: { diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp index b4b5f98609..d14a3014c8 100644 --- a/services/sensorservice/SensorEventConnection.cpp +++ b/services/sensorservice/SensorEventConnection.cpp @@ -28,6 +28,12 @@ #define UNUSED(x) (void)(x) namespace android { +namespace { + +// Used as the default value for the target SDK until it's obtained via getTargetSdkVersion. +constexpr int kTargetSdkUnknown = 0; + +} // namespace SensorService::SensorEventConnection::SensorEventConnection( const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode, @@ -35,9 +41,9 @@ SensorService::SensorEventConnection::SensorEventConnection( : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false), mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(nullptr), mCacheSize(0), mMaxCacheSize(0), mTimeOfLastEventDrop(0), mEventsDropped(0), - mPackageName(packageName), mOpPackageName(opPackageName), mDestroyed(false) { + mPackageName(packageName), mOpPackageName(opPackageName), mTargetSdk(kTargetSdkUnknown), + mDestroyed(false) { mChannel = new BitTube(mService->mSocketBufferSize); - mTargetSdk = SensorService::getTargetSdkVersion(opPackageName); #if DEBUG_CONNECTIONS mEventsReceived = mEventsSentFromCache = mEventsSent = 0; mTotalAcksNeeded = mTotalAcksReceived = 0; @@ -445,6 +451,14 @@ bool SensorService::SensorEventConnection::noteOpIfRequired(const sensors_event_ bool success = true; const auto iter = mHandleToAppOp.find(event.sensor); if (iter != mHandleToAppOp.end()) { + if (mTargetSdk == kTargetSdkUnknown) { + // getTargetSdkVersion returns -1 if it fails so this operation should only be run once + // per connection and then cached. Perform this here as opposed to in the constructor to + // avoid log spam for NDK/VNDK clients that don't use sensors guarded with permissions + // and pass in invalid op package names. + mTargetSdk = SensorService::getTargetSdkVersion(mOpPackageName); + } + // Special handling for step count/detect backwards compatibility: if the app's target SDK // is pre-Q, still permit delivering events to the app even if permission isn't granted // (since this permission was only introduced in Q) diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index 60f9cd90c8..3ca34bba1b 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -79,6 +79,8 @@ uint8_t SensorService::sHmacGlobalKey[128] = {}; bool SensorService::sHmacGlobalKeyIsValid = false; std::map<String16, int> SensorService::sPackageTargetVersion; Mutex SensorService::sPackageTargetVersionLock; +String16 SensorService::sSensorInterfaceDescriptorPrefix = + String16("android.frameworks.sensorservice@"); AppOpsManager SensorService::sAppOpsManager; #define SENSOR_SERVICE_DIR "/data/system/sensor_service" @@ -1847,6 +1849,13 @@ bool SensorService::hasPermissionForSensor(const Sensor& sensor) { } int SensorService::getTargetSdkVersion(const String16& opPackageName) { + // Don't query the SDK version for the ISensorManager descriptor as it doesn't have one. This + // descriptor tends to be used for VNDK clients, but can technically be set by anyone so don't + // give it elevated privileges. + if (opPackageName.startsWith(sSensorInterfaceDescriptorPrefix)) { + return -1; + } + Mutex::Autolock packageLock(sPackageTargetVersionLock); int targetSdkVersion = -1; auto entry = sPackageTargetVersion.find(opPackageName); diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h index 3bb8421a14..052cbfe290 100644 --- a/services/sensorservice/SensorService.h +++ b/services/sensorservice/SensorService.h @@ -424,6 +424,7 @@ private: static AppOpsManager sAppOpsManager; static std::map<String16, int> sPackageTargetVersion; static Mutex sPackageTargetVersionLock; + static String16 sSensorInterfaceDescriptorPrefix; }; } // namespace android |