Loading libs/binder/BufferedTextOutput.cpp +11 −2 Original line number Diff line number Diff line Loading @@ -48,9 +48,18 @@ struct BufferedTextOutput::BufferState : public RefBase } status_t append(const char* txt, size_t len) { if (len > SIZE_MAX - bufferPos) return NO_MEMORY; // overflow if (len > SIZE_MAX - bufferPos) { ALOGE("%s: expanding buffer length by %zu exceeds max size (bufferPos: %zu)\n", __FUNCTION__, len, bufferPos); return NO_MEMORY; // overflow } if ((len+bufferPos) > bufferSize) { if ((len + bufferPos) > SIZE_MAX / 3) return NO_MEMORY; // overflow if ((len + bufferPos) > SIZE_MAX / 3) { ALOGE("%s: cannot realloc to increase buffer size. Total length: %zu (len: %zu, " "bufferPos: %zu)", __FUNCTION__, len + bufferPos, len, bufferPos); return NO_MEMORY; // overflow } size_t newSize = ((len+bufferPos)*3)/2; void* b = realloc(buffer, newSize); if (!b) return NO_MEMORY; Loading libs/binder/MemoryDealer.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -374,6 +374,7 @@ ssize_t SimpleBestFitAllocator::alloc(size_t size, uint32_t flags) } return (free_chunk->start)*kMemoryAlign; } ALOGE("%s: no free chunk", __FUNCTION__); return NO_MEMORY; } Loading libs/binder/Parcel.cpp +69 −15 Original line number Diff line number Diff line Loading @@ -581,12 +581,26 @@ status_t Parcel::appendFrom(const Parcel* parcel, size_t offset, size_t len) { const sp<ProcessState> proc(ProcessState::self()); // grow objects if (kernelFields->mObjectsCapacity < kernelFields->mObjectsSize + numObjects) { if ((size_t)numObjects > SIZE_MAX - kernelFields->mObjectsSize) return NO_MEMORY; // overflow if (kernelFields->mObjectsSize + numObjects > SIZE_MAX / 3) if ((size_t)numObjects > SIZE_MAX - kernelFields->mObjectsSize) { ALOGE("%s: binder objects buffer overflow (newObjects: %d, currentObjects: " "%zu) - max size reached", __FUNCTION__, numObjects, kernelFields->mObjectsSize); return NO_MEMORY; // overflosw } if (kernelFields->mObjectsSize + numObjects > SIZE_MAX / 3) { ALOGE("%s: cannot realloc to handle additional binder objects (newObjects: %d, " "currentObjects: %zu) - overflow", __FUNCTION__, numObjects, kernelFields->mObjectsSize); return NO_MEMORY; // overflow } size_t newSize = ((kernelFields->mObjectsSize + numObjects) * 3) / 2; if (newSize > SIZE_MAX / sizeof(binder_size_t)) return NO_MEMORY; // overflow if (newSize > SIZE_MAX / sizeof(binder_size_t)) { ALOGE("%s: cannot realloc to handle additional binder objects for new size " "(newObjects: %d currentObjects: %zu) - " "overflow", __FUNCTION__, numObjects, kernelFields->mObjectsSize); return NO_MEMORY; // overflow } binder_size_t* objects = (binder_size_t*)realloc(kernelFields->mObjects, newSize * sizeof(binder_size_t)); if (objects == (binder_size_t*)nullptr) { Loading Loading @@ -1162,14 +1176,12 @@ status_t Parcel::finishWrite(size_t len) return BAD_VALUE; } //printf("Finish write of %d\n", len); mDataPos += len; ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos); if (mDataPos > mDataSize) { mDataSize = mDataPos; ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize); } //printf("New pos=%d, size=%d\n", mDataPos, mDataSize); return NO_ERROR; } Loading @@ -1194,6 +1206,7 @@ void* Parcel::writeInplace(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. ALOGI("%s: len %zu exceeds INT32_MAX (%d)", __FUNCTION__, len, INT32_MAX); return nullptr; } Loading @@ -1201,6 +1214,7 @@ void* Parcel::writeInplace(size_t len) // check for integer overflow if (mDataPos+padded < mDataPos) { ALOGI("%s: integer overflow (mDataPos: %zu padded: %zu)", __FUNCTION__, mDataPos, padded); return nullptr; } Loading @@ -1210,6 +1224,7 @@ restart_write: uint8_t* const data = mData+mDataPos; if (status_t status = validateReadData(mDataPos + padded); status != OK) { ALOGI("%s: validateReadData failed", __FUNCTION__); return nullptr; // drops status } Loading Loading @@ -1597,6 +1612,7 @@ status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership) { } size_t dataPos = mDataPos; if (dataPos > UINT32_MAX) { ALOGE("%s: dataPos %zu larger than MAX %u", __FUNCTION__, dataPos, UINT32_MAX); return NO_MEMORY; } if (status_t err = writeInt32(RpcFields::TYPE_NATIVE_FILE_DESCRIPTOR); err != OK) { Loading Loading @@ -1696,7 +1712,10 @@ status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob) ALOGV("writeBlob: write to ashmem"); int fd = ashmem_create_region("Parcel Blob", len); if (fd < 0) return NO_MEMORY; if (fd < 0) { ALOGE("%s: failed to create ashmem", __FUNCTION__); return NO_MEMORY; } int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE); if (result < 0) { Loading Loading @@ -1837,10 +1856,23 @@ restart_write: if (err != NO_ERROR) return err; } if (!enoughObjects) { if (kernelFields->mObjectsSize > SIZE_MAX - 2) return NO_MEMORY; // overflow if ((kernelFields->mObjectsSize + 2) > SIZE_MAX / 3) return NO_MEMORY; // overflow if (kernelFields->mObjectsSize > SIZE_MAX - 2) { ALOGE("%s: kernel binder objects overflow (objectsSize: %zu)", __FUNCTION__, kernelFields->mObjectsSize); return NO_MEMORY; // overflow } if ((kernelFields->mObjectsSize + 2) > SIZE_MAX / 3) { ALOGE("%s: cannot resize to handle additional kernel binder objects (objectsSize: %zu)", __FUNCTION__, kernelFields->mObjectsSize); return NO_MEMORY; // overflow } size_t newSize = ((kernelFields->mObjectsSize + 2) * 3) / 2; if (newSize > SIZE_MAX / sizeof(binder_size_t)) return NO_MEMORY; // overflow if (newSize > SIZE_MAX / sizeof(binder_size_t)) { ALOGE("%s: cannot resize to handle additional kernel binder objects with new size " "(objectsSize: %zu)", __FUNCTION__, newSize); return NO_MEMORY; // overflow } binder_size_t* objects = (binder_size_t*)realloc(kernelFields->mObjects, newSize * sizeof(binder_size_t)); if (objects == nullptr) return NO_MEMORY; Loading Loading @@ -2003,13 +2035,18 @@ status_t Parcel::readOutVectorSizeWithCheck(size_t elmSize, int32_t* size) const // allocations) static_assert(sizeof(int) == sizeof(int32_t), "Android is LP64"); int32_t allocationSize; if (__builtin_smul_overflow(elmSize, *size, &allocationSize)) return NO_MEMORY; if (__builtin_smul_overflow(elmSize, *size, &allocationSize)) { ALOGE("%s: smul_overflow failed (elmSize: %zu, size: %d)", __FUNCTION__, elmSize, *size); return NO_MEMORY; } // High limit of 1MB since something this big could never be returned. Could // probably scope this down, but might impact very specific usecases. constexpr int32_t kMaxAllocationSize = 1 * 1000 * 1000; if (allocationSize >= kMaxAllocationSize) { ALOGE("%s: allocation size %d larger than max allowed %d", __FUNCTION__, allocationSize, kMaxAllocationSize); return NO_MEMORY; } Loading Loading @@ -2566,7 +2603,10 @@ status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const } void* ptr = ::mmap(nullptr, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) return NO_MEMORY; if (ptr == MAP_FAILED) { ALOGE("%s: mmap failed", __FUNCTION__); return NO_MEMORY; } outBlob->init(fd, ptr, len, isMutable); return NO_ERROR; Loading Loading @@ -3040,9 +3080,22 @@ status_t Parcel::growData(size_t len) return BAD_VALUE; } if (len > SIZE_MAX - mDataSize) return NO_MEMORY; // overflow if (mDataSize + len > SIZE_MAX / 3) return NO_MEMORY; // overflow if (len > SIZE_MAX - mDataSize) { ALOGE("%s: attempt to grow data past the max size (len: %zu mDataSize: %zu)", __FUNCTION__, len, mDataSize); return NO_MEMORY; // overflow } if (mDataSize + len > SIZE_MAX / 3) { ALOGE("%s: cannot resize to grow data (len: %zu, mDataSize: %zu)", __FUNCTION__, len, mDataSize); return NO_MEMORY; // overflow } size_t newSize = ((mDataSize+len)*3)/2; if (newSize <= mDataSize) { ALOGE("%s: cannot resize to grow data even with newSize: %zu (mDataSize: %zu)", __FUNCTION__, newSize, mDataSize); } return (newSize <= mDataSize) ? (status_t) NO_MEMORY : continueWrite(std::max(newSize, (size_t) 128)); Loading Loading @@ -3080,7 +3133,8 @@ status_t Parcel::restartWrite(size_t desired) uint8_t* data = reallocZeroFree(mData, mDataCapacity, desired, mDeallocZero); if (!data && desired > mDataCapacity) { LOG_ALWAYS_FATAL("out of memory"); LOG_ALWAYS_FATAL("%s: realloc failed as desired size %zu is larger than capacity %zu", __FUNCTION__, desired, mDataCapacity); mError = NO_MEMORY; return NO_MEMORY; } Loading libs/binder/RpcState.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ status_t RpcState::onBinderLeaving(const sp<RpcSession>& session, const sp<IBind // arbitrary limit for maximum number of nodes in a process (otherwise we // might run out of addresses) if (mNodeForAddress.size() > 100000) { ALOGE("%s: too many nodes in the process (%zu)", __FUNCTION__, mNodeForAddress.size()); return NO_MEMORY; } Loading libs/binder/RpcTransportTipcAndroid.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -190,6 +190,7 @@ private: if (savedErrno == EMSGSIZE) { // Buffer was too small, double it and retry if (__builtin_mul_overflow(mReadBufferCapacity, 2, &mReadBufferCapacity)) { ALOGE("%s: read buffer mul_overflow", __FUNCTION__); return NO_MEMORY; } mReadBuffer.reset(new (std::nothrow) uint8_t[mReadBufferCapacity]); Loading Loading
libs/binder/BufferedTextOutput.cpp +11 −2 Original line number Diff line number Diff line Loading @@ -48,9 +48,18 @@ struct BufferedTextOutput::BufferState : public RefBase } status_t append(const char* txt, size_t len) { if (len > SIZE_MAX - bufferPos) return NO_MEMORY; // overflow if (len > SIZE_MAX - bufferPos) { ALOGE("%s: expanding buffer length by %zu exceeds max size (bufferPos: %zu)\n", __FUNCTION__, len, bufferPos); return NO_MEMORY; // overflow } if ((len+bufferPos) > bufferSize) { if ((len + bufferPos) > SIZE_MAX / 3) return NO_MEMORY; // overflow if ((len + bufferPos) > SIZE_MAX / 3) { ALOGE("%s: cannot realloc to increase buffer size. Total length: %zu (len: %zu, " "bufferPos: %zu)", __FUNCTION__, len + bufferPos, len, bufferPos); return NO_MEMORY; // overflow } size_t newSize = ((len+bufferPos)*3)/2; void* b = realloc(buffer, newSize); if (!b) return NO_MEMORY; Loading
libs/binder/MemoryDealer.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -374,6 +374,7 @@ ssize_t SimpleBestFitAllocator::alloc(size_t size, uint32_t flags) } return (free_chunk->start)*kMemoryAlign; } ALOGE("%s: no free chunk", __FUNCTION__); return NO_MEMORY; } Loading
libs/binder/Parcel.cpp +69 −15 Original line number Diff line number Diff line Loading @@ -581,12 +581,26 @@ status_t Parcel::appendFrom(const Parcel* parcel, size_t offset, size_t len) { const sp<ProcessState> proc(ProcessState::self()); // grow objects if (kernelFields->mObjectsCapacity < kernelFields->mObjectsSize + numObjects) { if ((size_t)numObjects > SIZE_MAX - kernelFields->mObjectsSize) return NO_MEMORY; // overflow if (kernelFields->mObjectsSize + numObjects > SIZE_MAX / 3) if ((size_t)numObjects > SIZE_MAX - kernelFields->mObjectsSize) { ALOGE("%s: binder objects buffer overflow (newObjects: %d, currentObjects: " "%zu) - max size reached", __FUNCTION__, numObjects, kernelFields->mObjectsSize); return NO_MEMORY; // overflosw } if (kernelFields->mObjectsSize + numObjects > SIZE_MAX / 3) { ALOGE("%s: cannot realloc to handle additional binder objects (newObjects: %d, " "currentObjects: %zu) - overflow", __FUNCTION__, numObjects, kernelFields->mObjectsSize); return NO_MEMORY; // overflow } size_t newSize = ((kernelFields->mObjectsSize + numObjects) * 3) / 2; if (newSize > SIZE_MAX / sizeof(binder_size_t)) return NO_MEMORY; // overflow if (newSize > SIZE_MAX / sizeof(binder_size_t)) { ALOGE("%s: cannot realloc to handle additional binder objects for new size " "(newObjects: %d currentObjects: %zu) - " "overflow", __FUNCTION__, numObjects, kernelFields->mObjectsSize); return NO_MEMORY; // overflow } binder_size_t* objects = (binder_size_t*)realloc(kernelFields->mObjects, newSize * sizeof(binder_size_t)); if (objects == (binder_size_t*)nullptr) { Loading Loading @@ -1162,14 +1176,12 @@ status_t Parcel::finishWrite(size_t len) return BAD_VALUE; } //printf("Finish write of %d\n", len); mDataPos += len; ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos); if (mDataPos > mDataSize) { mDataSize = mDataPos; ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize); } //printf("New pos=%d, size=%d\n", mDataPos, mDataSize); return NO_ERROR; } Loading @@ -1194,6 +1206,7 @@ void* Parcel::writeInplace(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. ALOGI("%s: len %zu exceeds INT32_MAX (%d)", __FUNCTION__, len, INT32_MAX); return nullptr; } Loading @@ -1201,6 +1214,7 @@ void* Parcel::writeInplace(size_t len) // check for integer overflow if (mDataPos+padded < mDataPos) { ALOGI("%s: integer overflow (mDataPos: %zu padded: %zu)", __FUNCTION__, mDataPos, padded); return nullptr; } Loading @@ -1210,6 +1224,7 @@ restart_write: uint8_t* const data = mData+mDataPos; if (status_t status = validateReadData(mDataPos + padded); status != OK) { ALOGI("%s: validateReadData failed", __FUNCTION__); return nullptr; // drops status } Loading Loading @@ -1597,6 +1612,7 @@ status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership) { } size_t dataPos = mDataPos; if (dataPos > UINT32_MAX) { ALOGE("%s: dataPos %zu larger than MAX %u", __FUNCTION__, dataPos, UINT32_MAX); return NO_MEMORY; } if (status_t err = writeInt32(RpcFields::TYPE_NATIVE_FILE_DESCRIPTOR); err != OK) { Loading Loading @@ -1696,7 +1712,10 @@ status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob) ALOGV("writeBlob: write to ashmem"); int fd = ashmem_create_region("Parcel Blob", len); if (fd < 0) return NO_MEMORY; if (fd < 0) { ALOGE("%s: failed to create ashmem", __FUNCTION__); return NO_MEMORY; } int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE); if (result < 0) { Loading Loading @@ -1837,10 +1856,23 @@ restart_write: if (err != NO_ERROR) return err; } if (!enoughObjects) { if (kernelFields->mObjectsSize > SIZE_MAX - 2) return NO_MEMORY; // overflow if ((kernelFields->mObjectsSize + 2) > SIZE_MAX / 3) return NO_MEMORY; // overflow if (kernelFields->mObjectsSize > SIZE_MAX - 2) { ALOGE("%s: kernel binder objects overflow (objectsSize: %zu)", __FUNCTION__, kernelFields->mObjectsSize); return NO_MEMORY; // overflow } if ((kernelFields->mObjectsSize + 2) > SIZE_MAX / 3) { ALOGE("%s: cannot resize to handle additional kernel binder objects (objectsSize: %zu)", __FUNCTION__, kernelFields->mObjectsSize); return NO_MEMORY; // overflow } size_t newSize = ((kernelFields->mObjectsSize + 2) * 3) / 2; if (newSize > SIZE_MAX / sizeof(binder_size_t)) return NO_MEMORY; // overflow if (newSize > SIZE_MAX / sizeof(binder_size_t)) { ALOGE("%s: cannot resize to handle additional kernel binder objects with new size " "(objectsSize: %zu)", __FUNCTION__, newSize); return NO_MEMORY; // overflow } binder_size_t* objects = (binder_size_t*)realloc(kernelFields->mObjects, newSize * sizeof(binder_size_t)); if (objects == nullptr) return NO_MEMORY; Loading Loading @@ -2003,13 +2035,18 @@ status_t Parcel::readOutVectorSizeWithCheck(size_t elmSize, int32_t* size) const // allocations) static_assert(sizeof(int) == sizeof(int32_t), "Android is LP64"); int32_t allocationSize; if (__builtin_smul_overflow(elmSize, *size, &allocationSize)) return NO_MEMORY; if (__builtin_smul_overflow(elmSize, *size, &allocationSize)) { ALOGE("%s: smul_overflow failed (elmSize: %zu, size: %d)", __FUNCTION__, elmSize, *size); return NO_MEMORY; } // High limit of 1MB since something this big could never be returned. Could // probably scope this down, but might impact very specific usecases. constexpr int32_t kMaxAllocationSize = 1 * 1000 * 1000; if (allocationSize >= kMaxAllocationSize) { ALOGE("%s: allocation size %d larger than max allowed %d", __FUNCTION__, allocationSize, kMaxAllocationSize); return NO_MEMORY; } Loading Loading @@ -2566,7 +2603,10 @@ status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const } void* ptr = ::mmap(nullptr, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) return NO_MEMORY; if (ptr == MAP_FAILED) { ALOGE("%s: mmap failed", __FUNCTION__); return NO_MEMORY; } outBlob->init(fd, ptr, len, isMutable); return NO_ERROR; Loading Loading @@ -3040,9 +3080,22 @@ status_t Parcel::growData(size_t len) return BAD_VALUE; } if (len > SIZE_MAX - mDataSize) return NO_MEMORY; // overflow if (mDataSize + len > SIZE_MAX / 3) return NO_MEMORY; // overflow if (len > SIZE_MAX - mDataSize) { ALOGE("%s: attempt to grow data past the max size (len: %zu mDataSize: %zu)", __FUNCTION__, len, mDataSize); return NO_MEMORY; // overflow } if (mDataSize + len > SIZE_MAX / 3) { ALOGE("%s: cannot resize to grow data (len: %zu, mDataSize: %zu)", __FUNCTION__, len, mDataSize); return NO_MEMORY; // overflow } size_t newSize = ((mDataSize+len)*3)/2; if (newSize <= mDataSize) { ALOGE("%s: cannot resize to grow data even with newSize: %zu (mDataSize: %zu)", __FUNCTION__, newSize, mDataSize); } return (newSize <= mDataSize) ? (status_t) NO_MEMORY : continueWrite(std::max(newSize, (size_t) 128)); Loading Loading @@ -3080,7 +3133,8 @@ status_t Parcel::restartWrite(size_t desired) uint8_t* data = reallocZeroFree(mData, mDataCapacity, desired, mDeallocZero); if (!data && desired > mDataCapacity) { LOG_ALWAYS_FATAL("out of memory"); LOG_ALWAYS_FATAL("%s: realloc failed as desired size %zu is larger than capacity %zu", __FUNCTION__, desired, mDataCapacity); mError = NO_MEMORY; return NO_MEMORY; } Loading
libs/binder/RpcState.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ status_t RpcState::onBinderLeaving(const sp<RpcSession>& session, const sp<IBind // arbitrary limit for maximum number of nodes in a process (otherwise we // might run out of addresses) if (mNodeForAddress.size() > 100000) { ALOGE("%s: too many nodes in the process (%zu)", __FUNCTION__, mNodeForAddress.size()); return NO_MEMORY; } Loading
libs/binder/RpcTransportTipcAndroid.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -190,6 +190,7 @@ private: if (savedErrno == EMSGSIZE) { // Buffer was too small, double it and retry if (__builtin_mul_overflow(mReadBufferCapacity, 2, &mReadBufferCapacity)) { ALOGE("%s: read buffer mul_overflow", __FUNCTION__); return NO_MEMORY; } mReadBuffer.reset(new (std::nothrow) uint8_t[mReadBufferCapacity]); Loading