diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-06-11 22:26:13 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-06-11 22:26:13 +0000 |
commit | f09b03874be719bc1a8ceb6ea699c1c88345cae8 (patch) | |
tree | fe4081a0bbd50570afdb060c0cda57b68f20a67c | |
parent | b11fdc57a5b84ed3a04cf99d7c5b4b23e3631290 (diff) | |
parent | 9b2d407283f3c62afeccbd6d8e6dcc7824b598c4 (diff) | |
download | native-oreo-m2-s5-release.tar.gz |
Merge cherrypicks of [4314166, 4314167, 4314168, 4314169, 4314462, 4314463, 4314464, 4314465, 4314466, 4314643, 4314644, 4314185, 4314467, 4314468, 4315341, 4315342, 4315343, 4315344, 4315345, 4314469, 4314283, 4314186, 4314187, 4314188, 4314189, 4314190, 4314191, 4314192, 4315082, 4315083, 4315084, 4315085, 4315086, 4315087, 4315088, 4315089, 4315090, 4315091, 4315092, 4314170, 4314284, 4314285, 4314286, 4314287, 4314171, 4314172, 4315346, 4314288, 4315381, 4315401, 4315402, 4314289, 4314290, 4314291, 4314292, 4314293, 4314294, 4314295, 4314296, 4314297, 4314298, 4314299, 4314300, 4315421, 4315422, 4314034, 4314229, 4315347, 4315423, 4315424, 4315314, 4315348, 4315349, 4314470, 4315425, 4315426, 4315427, 4315428, 4315429] into sparse-4732990-L02900000181396755android-8.1.0_r36oreo-m2-s5-release
Change-Id: I873d5471d689a25b5171fed6cedcd86fe676600a
-rw-r--r-- | libs/binder/Parcel.cpp | 89 | ||||
-rw-r--r-- | libs/binder/include/binder/Parcel.h | 2 |
2 files changed, 90 insertions, 1 deletions
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index e22179b15d..460bbe2fc5 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -433,6 +433,7 @@ void Parcel::setDataPosition(size_t pos) const mDataPos = pos; mNextObjectHint = 0; + mObjectsSorted = false; } status_t Parcel::setDataCapacity(size_t size) @@ -1276,7 +1277,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(len); if (buf == NULL) return BAD_VALUE; @@ -1469,6 +1470,59 @@ void Parcel::remove(size_t /*start*/, size_t /*amt*/) LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!"); } +status_t Parcel::validateReadData(size_t upperBound) const +{ + // Don't allow non-object reads on object data + if (mObjectsSorted || mObjectsSize <= 1) { +data_sorted: + // Expect to check only against the next object + if (mNextObjectHint < mObjectsSize && upperBound > mObjects[mNextObjectHint]) { + // For some reason the current read position is greater than the next object + // hint. Iterate until we find the right object + size_t nextObject = mNextObjectHint; + do { + if (mDataPos < mObjects[nextObject] + sizeof(flat_binder_object)) { + // Requested info overlaps with an object + ALOGE("Attempt to read from protected data in Parcel %p", this); + return PERMISSION_DENIED; + } + nextObject++; + } while (nextObject < mObjectsSize && upperBound > mObjects[nextObject]); + mNextObjectHint = nextObject; + } + return NO_ERROR; + } + // Quickly determine if mObjects is sorted. + binder_size_t* currObj = mObjects + mObjectsSize - 1; + binder_size_t* prevObj = currObj; + while (currObj > mObjects) { + prevObj--; + if(*prevObj > *currObj) { + goto data_unsorted; + } + currObj--; + } + mObjectsSorted = true; + goto data_sorted; + +data_unsorted: + // Insertion Sort mObjects + // Great for mostly sorted lists. If randomly sorted or reverse ordered mObjects become common, + // switch to std::sort(mObjects, mObjects + mObjectsSize); + for (binder_size_t* iter0 = mObjects + 1; iter0 < mObjects + mObjectsSize; iter0++) { + binder_size_t temp = *iter0; + binder_size_t* iter1 = iter0 - 1; + while (iter1 >= mObjects && *iter1 > temp) { + *(iter1 + 1) = *iter1; + iter1--; + } + *(iter1 + 1) = temp; + } + mNextObjectHint = 0; + mObjectsSorted = true; + goto data_sorted; +} + status_t Parcel::read(void* outData, size_t len) const { if (len > INT32_MAX) { @@ -1479,6 +1533,15 @@ 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 (mObjectsSize > 0) { + status_t err = validateReadData(mDataPos + pad_size(len)); + if(err != NO_ERROR) { + // Still increment the data position by the expected length + mDataPos += pad_size(len); + ALOGV("read Setting data pos of %p to %zu", this, mDataPos); + return err; + } + } memcpy(outData, mData+mDataPos, len); mDataPos += pad_size(len); ALOGV("read Setting data pos of %p to %zu", this, mDataPos); @@ -1497,6 +1560,16 @@ const void* Parcel::readInplace(size_t len) const if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize && len <= pad_size(len)) { + if (mObjectsSize > 0) { + status_t err = validateReadData(mDataPos + pad_size(len)); + if(err != NO_ERROR) { + // Still increment the data position by the expected length + mDataPos += pad_size(len); + ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos); + return NULL; + } + } + const void* data = mData+mDataPos; mDataPos += pad_size(len); ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos); @@ -1510,6 +1583,15 @@ status_t Parcel::readAligned(T *pArg) const { COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); if ((mDataPos+sizeof(T)) <= mDataSize) { + if (mObjectsSize > 0) { + status_t err = validateReadData(mDataPos + sizeof(T)); + if(err != NO_ERROR) { + // Still increment the data position by the expected length + mDataPos += sizeof(T); + return err; + } + } + const void* data = mData+mDataPos; mDataPos += sizeof(T); *pArg = *reinterpret_cast<const T*>(data); @@ -2366,6 +2448,7 @@ void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize, mObjects = const_cast<binder_size_t*>(objects); mObjectsSize = mObjectsCapacity = objectsCount; mNextObjectHint = 0; + mObjectsSorted = false; mOwner = relFunc; mOwnerCookie = relCookie; for (size_t i = 0; i < mObjectsSize; i++) { @@ -2524,6 +2607,7 @@ status_t Parcel::restartWrite(size_t desired) mObjects = NULL; mObjectsSize = mObjectsCapacity = 0; mNextObjectHint = 0; + mObjectsSorted = false; mHasFds = false; mFdsKnown = true; mAllowFds = true; @@ -2610,6 +2694,7 @@ status_t Parcel::continueWrite(size_t desired) mDataCapacity = desired; mObjectsSize = mObjectsCapacity = objectsSize; mNextObjectHint = 0; + mObjectsSorted = false; } else if (mData) { if (objectsSize < mObjectsSize) { @@ -2631,6 +2716,7 @@ status_t Parcel::continueWrite(size_t desired) } mObjectsSize = objectsSize; mNextObjectHint = 0; + mObjectsSorted = false; } // We own the data, so we can just do a realloc(). @@ -2703,6 +2789,7 @@ void Parcel::initState() mObjectsSize = 0; mObjectsCapacity = 0; mNextObjectHint = 0; + mObjectsSorted = false; mHasFds = false; mFdsKnown = true; mAllowFds = true; diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h index 5d36526cb3..dede78f61e 100644 --- a/libs/binder/include/binder/Parcel.h +++ b/libs/binder/include/binder/Parcel.h @@ -417,6 +417,7 @@ private: void freeDataNoInit(); void initState(); void scanForFds() const; + status_t validateReadData(size_t len) const; template<class T> status_t readAligned(T *pArg) const; @@ -463,6 +464,7 @@ private: size_t mObjectsSize; size_t mObjectsCapacity; mutable size_t mNextObjectHint; + mutable bool mObjectsSorted; mutable bool mFdsKnown; mutable bool mHasFds; |