diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/binder/Android.mk | 2 | ||||
| -rw-r--r-- | libs/binder/IInterface.cpp | 21 | ||||
| -rw-r--r-- | libs/binder/IProcessInfoService.cpp | 94 | ||||
| -rw-r--r-- | libs/binder/Parcel.cpp | 165 | ||||
| -rw-r--r-- | libs/binder/ProcessInfoService.cpp | 70 | ||||
| -rw-r--r-- | libs/gui/ISensorServer.cpp | 6 | ||||
| -rw-r--r-- | libs/gui/SensorManager.cpp | 4 | ||||
| -rw-r--r-- | libs/input/Android.mk | 1 | ||||
| -rw-r--r-- | libs/input/IInputFlinger.cpp | 59 |
9 files changed, 405 insertions, 17 deletions
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk index 79decfe21f..d5860ef6ca 100644 --- a/libs/binder/Android.mk +++ b/libs/binder/Android.mk @@ -26,6 +26,8 @@ sources := \ IMemory.cpp \ IPCThreadState.cpp \ IPermissionController.cpp \ + IProcessInfoService.cpp \ + ProcessInfoService.cpp \ IServiceManager.cpp \ MemoryDealer.cpp \ MemoryBase.cpp \ diff --git a/libs/binder/IInterface.cpp b/libs/binder/IInterface.cpp index 8c60dc4f7e..2fcd3d92fb 100644 --- a/libs/binder/IInterface.cpp +++ b/libs/binder/IInterface.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "IInterface" +#include <utils/Log.h> #include <binder/IInterface.h> namespace android { @@ -41,6 +43,25 @@ sp<IBinder> IInterface::asBinder(const sp<IInterface>& iface) return iface->onAsBinder(); } + // --------------------------------------------------------------------------- }; // namespace android + +extern "C" { + +void _ZN7android10IInterface8asBinderEv(void *retval, void* self) { + ALOGW("deprecated asBinder call, please update your code"); + //ALOGI("self: %p, retval: %p", self, retval); + android::sp<android::IBinder> *ret = new(retval) android::sp<android::IBinder>; + *ret = android::IInterface::asBinder((android::IInterface*)self); +} + +void _ZNK7android10IInterface8asBinderEv(void *retval, void *self) { + ALOGW("deprecated asBinder call, please update your code"); + //ALOGI("self: %p, retval: %p", self, retval); + android::sp<android::IBinder> *ret = new(retval) android::sp<android::IBinder>; + *ret = android::IInterface::asBinder((android::IInterface*)self); +} + +} // extern "C" diff --git a/libs/binder/IProcessInfoService.cpp b/libs/binder/IProcessInfoService.cpp new file mode 100644 index 0000000000..d86eb27b4d --- /dev/null +++ b/libs/binder/IProcessInfoService.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2015 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/IProcessInfoService.h> +#include <binder/Parcel.h> +#include <utils/Errors.h> +#include <sys/types.h> + +namespace android { + +// ---------------------------------------------------------------------- + +class BpProcessInfoService : public BpInterface<IProcessInfoService> { +public: + BpProcessInfoService(const sp<IBinder>& impl) + : BpInterface<IProcessInfoService>(impl) {} + + virtual status_t getProcessStatesFromPids(size_t length, /*in*/ int32_t* pids, + /*out*/ int32_t* states) + { + Parcel data, reply; + data.writeInterfaceToken(IProcessInfoService::getInterfaceDescriptor()); + data.writeInt32Array(length, pids); + data.writeInt32(length); // write length of output array, used by java AIDL stubs + status_t err = remote()->transact(GET_PROCESS_STATES_FROM_PIDS, data, &reply); + if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) { + return err; + } + int32_t replyLen = reply.readInt32(); + if (static_cast<size_t>(replyLen) != length) { + return NOT_ENOUGH_DATA; + } + if (replyLen > 0 && (err = reply.read(states, length * sizeof(*states))) != NO_ERROR) { + return err; + } + return reply.readInt32(); + } + +}; + +IMPLEMENT_META_INTERFACE(ProcessInfoService, "android.os.IProcessInfoService"); + +// ---------------------------------------------------------------------- + +status_t BnProcessInfoService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, + uint32_t flags) { + switch(code) { + case GET_PROCESS_STATES_FROM_PIDS: { + CHECK_INTERFACE(IProcessInfoService, data, reply); + int32_t arrayLen = data.readInt32(); + if (arrayLen <= 0) { + reply->writeNoException(); + reply->writeInt32(0); + reply->writeInt32(NOT_ENOUGH_DATA); + return NO_ERROR; + } + + size_t len = static_cast<size_t>(arrayLen); + int32_t pids[len]; + status_t res = data.read(pids, len * sizeof(*pids)); + + // Ignore output array length returned in the parcel here, as the states array must + // always be the same length as the input PIDs array. + int32_t states[len]; + for (size_t i = 0; i < len; i++) states[i] = -1; + if (res == NO_ERROR) { + res = getProcessStatesFromPids(len, /*in*/ pids, /*out*/ states); + } + reply->writeNoException(); + reply->writeInt32Array(len, states); + reply->writeInt32(res); + return NO_ERROR; + } break; + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +// ---------------------------------------------------------------------- + +}; // namespace android diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 2c566f9655..d4dd8c7f29 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -54,7 +54,17 @@ // --------------------------------------------------------------------------- -#define PAD_SIZE(s) (((s)+3)&~3) +// This macro should never be used at runtime, as a too large value +// of s could cause an integer overflow. Instead, you should always +// use the wrapper function pad_size() +#define PAD_SIZE_UNSAFE(s) (((s)+3)&~3) + +static size_t pad_size(size_t s) { + if (s > (SIZE_T_MAX - 3)) { + abort(); + } + return PAD_SIZE_UNSAFE(s); +} // Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER #define STRICT_MODE_PENALTY_GATHER (0x40 << 16) @@ -355,6 +365,12 @@ size_t Parcel::dataCapacity() const status_t Parcel::setDataSize(size_t size) { + if (size > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + status_t err; err = continueWrite(size); if (err == NO_ERROR) { @@ -366,18 +382,36 @@ status_t Parcel::setDataSize(size_t size) void Parcel::setDataPosition(size_t pos) const { + if (pos > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + abort(); + } + mDataPos = pos; mNextObjectHint = 0; } status_t Parcel::setDataCapacity(size_t size) { + if (size > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + if (size > mDataCapacity) return continueWrite(size); return NO_ERROR; } status_t Parcel::setData(const uint8_t* buffer, size_t len) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + status_t err = restartWrite(len); if (err == NO_ERROR) { memcpy(const_cast<uint8_t*>(data()), buffer, len); @@ -401,6 +435,12 @@ status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len) return NO_ERROR; } + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + // range checks against the source parcel size if ((offset > parcel->mDataSize) || (len > parcel->mDataSize) @@ -561,6 +601,12 @@ void Parcel::setError(status_t err) status_t Parcel::finishWrite(size_t len) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + //printf("Finish write of %d\n", len); mDataPos += len; ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos); @@ -574,6 +620,12 @@ status_t Parcel::finishWrite(size_t len) status_t Parcel::writeUnpadded(const void* data, size_t len) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + size_t end = mDataPos + len; if (end < mDataPos) { // integer overflow @@ -593,6 +645,12 @@ restart_write: status_t Parcel::write(const void* data, size_t len) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + void* const d = writeInplace(len); if (d) { memcpy(d, data, len); @@ -603,7 +661,13 @@ status_t Parcel::write(const void* data, size_t len) void* Parcel::writeInplace(size_t len) { - const size_t padded = PAD_SIZE(len); + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return NULL; + } + + const size_t padded = pad_size(len); // sanity check for integer overflow if (mDataPos+padded < mDataPos) { @@ -652,6 +716,12 @@ status_t Parcel::writeUint32(uint32_t val) } status_t Parcel::writeInt32Array(size_t len, const int32_t *val) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + if (!val) { return writeAligned(-1); } @@ -662,6 +732,12 @@ status_t Parcel::writeInt32Array(size_t len, const int32_t *val) { return ret; } status_t Parcel::writeByteArray(size_t len, const uint8_t *val) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + if (!val) { return writeAligned(-1); } @@ -677,6 +753,11 @@ status_t Parcel::writeInt64(int64_t val) return writeAligned(val); } +status_t Parcel::writeUint64(uint64_t val) +{ + return writeAligned(val); +} + status_t Parcel::writePointer(uintptr_t val) { return writeAligned<binder_uintptr_t>(val); @@ -835,6 +916,12 @@ status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob) { status_t status; + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + if (!mAllowFds || len <= IN_PLACE_BLOB_LIMIT) { ALOGV("writeBlob: write in place"); status = writeInt32(0); @@ -887,6 +974,12 @@ status_t Parcel::write(const FlattenableHelperInterface& val) const size_t len = val.getFlattenedSize(); const size_t fd_count = val.getFdCount(); + if ((len > INT32_MAX) || (fd_count > INT32_MAX)) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + err = this->writeInt32(len); if (err) return err; @@ -894,7 +987,7 @@ status_t Parcel::write(const FlattenableHelperInterface& val) if (err) return err; // payload - void* const buf = this->writeInplace(PAD_SIZE(len)); + void* const buf = this->writeInplace(pad_size(len)); if (buf == NULL) return BAD_VALUE; @@ -968,10 +1061,16 @@ void Parcel::remove(size_t /*start*/, size_t /*amt*/) status_t Parcel::read(void* outData, size_t len) const { - if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize - && len <= PAD_SIZE(len)) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + + if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize + && len <= pad_size(len)) { memcpy(outData, mData+mDataPos, len); - mDataPos += PAD_SIZE(len); + mDataPos += pad_size(len); ALOGV("read Setting data pos of %p to %zu", this, mDataPos); return NO_ERROR; } @@ -980,10 +1079,16 @@ status_t Parcel::read(void* outData, size_t len) const const void* Parcel::readInplace(size_t len) const { - if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize - && len <= PAD_SIZE(len)) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return NULL; + } + + if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize + && len <= pad_size(len)) { const void* data = mData+mDataPos; - mDataPos += PAD_SIZE(len); + mDataPos += pad_size(len); ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos); return data; } @@ -992,7 +1097,7 @@ const void* Parcel::readInplace(size_t len) const template<class T> status_t Parcel::readAligned(T *pArg) const { - COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T)); + COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); if ((mDataPos+sizeof(T)) <= mDataSize) { const void* data = mData+mDataPos; @@ -1016,7 +1121,7 @@ T Parcel::readAligned() const { template<class T> status_t Parcel::writeAligned(T val) { - COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T)); + COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); if ((mDataPos+sizeof(val)) <= mDataCapacity) { restart_write: @@ -1060,6 +1165,16 @@ int64_t Parcel::readInt64() const return readAligned<int64_t>(); } +status_t Parcel::readUint64(uint64_t *pArg) const +{ + return readAligned(pArg); +} + +uint64_t Parcel::readUint64() const +{ + return readAligned<uint64_t>(); +} + status_t Parcel::readPointer(uintptr_t *pArg) const { status_t ret; @@ -1147,7 +1262,7 @@ const char* Parcel::readCString() const const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail)); if (eos) { const size_t len = eos - str; - mDataPos += PAD_SIZE(len+1); + mDataPos += pad_size(len+1); ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos); return str; } @@ -1306,8 +1421,14 @@ status_t Parcel::read(FlattenableHelperInterface& val) const const size_t len = this->readInt32(); const size_t fd_count = this->readInt32(); + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + // payload - void const* const buf = this->readInplace(PAD_SIZE(len)); + void const* const buf = this->readInplace(pad_size(len)); if (buf == NULL) return BAD_VALUE; @@ -1546,6 +1667,12 @@ void Parcel::freeDataNoInit() status_t Parcel::growData(size_t len) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + size_t newSize = ((mDataSize+len)*3)/2; return (newSize <= mDataSize) ? (status_t) NO_MEMORY @@ -1554,6 +1681,12 @@ status_t Parcel::growData(size_t len) status_t Parcel::restartWrite(size_t desired) { + if (desired > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + if (mOwner) { freeData(); return continueWrite(desired); @@ -1594,6 +1727,12 @@ status_t Parcel::restartWrite(size_t desired) status_t Parcel::continueWrite(size_t desired) { + if (desired > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + // If shrinking, first adjust for any objects that appear // after the new data size. size_t objectsSize = mObjectsSize; diff --git a/libs/binder/ProcessInfoService.cpp b/libs/binder/ProcessInfoService.cpp new file mode 100644 index 0000000000..fb2864355d --- /dev/null +++ b/libs/binder/ProcessInfoService.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2015 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/ProcessInfoService.h> +#include <binder/IServiceManager.h> + +#include <utils/Log.h> +#include <utils/String16.h> + +namespace android { + +ProcessInfoService::ProcessInfoService() { + updateBinderLocked(); +} + +status_t ProcessInfoService::getProcessStatesImpl(size_t length, /*in*/ int32_t* pids, + /*out*/ int32_t* states) { + status_t err = NO_ERROR; + sp<IProcessInfoService> pis; + mProcessInfoLock.lock(); + pis = mProcessInfoService; + mProcessInfoLock.unlock(); + + for (int i = 0; i < BINDER_ATTEMPT_LIMIT; i++) { + + if (pis != NULL) { + err = pis->getProcessStatesFromPids(length, /*in*/ pids, /*out*/ states); + if (err == NO_ERROR) return NO_ERROR; // success + if (IInterface::asBinder(pis)->isBinderAlive()) return err; + } + sleep(1); + + mProcessInfoLock.lock(); + if (pis == mProcessInfoService) { + updateBinderLocked(); + } + pis = mProcessInfoService; + mProcessInfoLock.unlock(); + } + + ALOGW("%s: Could not retrieve process states from ProcessInfoService after %d retries.", + __FUNCTION__, BINDER_ATTEMPT_LIMIT); + + return TIMED_OUT; +} + +void ProcessInfoService::updateBinderLocked() { + const sp<IServiceManager> sm(defaultServiceManager()); + if (sm != NULL) { + const String16 name("processinfo"); + mProcessInfoService = interface_cast<IProcessInfoService>(sm->checkService(name)); + } +} + +ANDROID_SINGLETON_STATIC_INSTANCE(ProcessInfoService); + +}; // namespace android diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp index 8e09e7ca73..3c85ec0f99 100644 --- a/libs/gui/ISensorServer.cpp +++ b/libs/gui/ISensorServer.cpp @@ -63,10 +63,11 @@ public: return v; } - virtual sp<ISensorEventConnection> createSensorEventConnection() + virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName) { Parcel data, reply; data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor()); + data.writeString8(packageName); remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply); return interface_cast<ISensorEventConnection>(reply.readStrongBinder()); } @@ -96,7 +97,8 @@ status_t BnSensorServer::onTransact( } case CREATE_SENSOR_EVENT_CONNECTION: { CHECK_INTERFACE(ISensorServer, data, reply); - sp<ISensorEventConnection> connection(createSensorEventConnection()); + String8 packageName = data.readString8(); + sp<ISensorEventConnection> connection(createSensorEventConnection(packageName)); reply->writeStrongBinder(IInterface::asBinder(connection)); return NO_ERROR; } diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp index d6df40407d..142c6ec090 100644 --- a/libs/gui/SensorManager.cpp +++ b/libs/gui/SensorManager.cpp @@ -139,14 +139,14 @@ Sensor const* SensorManager::getDefaultSensor(int type) return NULL; } -sp<SensorEventQueue> SensorManager::createEventQueue() +sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName) { sp<SensorEventQueue> queue; Mutex::Autolock _l(mLock); while (assertStateLocked() == NO_ERROR) { sp<ISensorEventConnection> connection = - mSensorServer->createSensorEventConnection(); + mSensorServer->createSensorEventConnection(packageName); if (connection == NULL) { // SensorService just died. ALOGE("createEventQueue: connection is NULL. SensorService died."); diff --git a/libs/input/Android.mk b/libs/input/Android.mk index f1921a4e0d..944ac7f653 100644 --- a/libs/input/Android.mk +++ b/libs/input/Android.mk @@ -27,6 +27,7 @@ commonSources := \ deviceSources := \ $(commonSources) \ + IInputFlinger.cpp \ InputTransport.cpp \ VelocityControl.cpp \ VelocityTracker.cpp diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp new file mode 100644 index 0000000000..e00973149c --- /dev/null +++ b/libs/input/IInputFlinger.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2013 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 <stdint.h> +#include <sys/types.h> + +#include <binder/Parcel.h> +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> + +#include <input/IInputFlinger.h> + + +namespace android { + +class BpInputFlinger : public BpInterface<IInputFlinger> { +public: + BpInputFlinger(const sp<IBinder>& impl) : + BpInterface<IInputFlinger>(impl) { } + + virtual status_t doSomething() { + Parcel data, reply; + data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor()); + remote()->transact(BnInputFlinger::DO_SOMETHING_TRANSACTION, data, &reply); + return reply.readInt32(); + } +}; + +IMPLEMENT_META_INTERFACE(InputFlinger, "android.input.IInputFlinger"); + + +status_t BnInputFlinger::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { + switch(code) { + case DO_SOMETHING_TRANSACTION: { + CHECK_INTERFACE(IInputFlinger, data, reply); + reply->writeInt32(0); + break; + } + default: + return BBinder::onTransact(code, data, reply, flags); + } + return NO_ERROR; +} + +}; |