diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-08-10 20:32:14 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-08-10 20:32:14 +0000 |
commit | e31f6eb5c49e0e638585243ac36ce139b60a6fb1 (patch) | |
tree | 1f5b5297a06eb215839a8e35fc5365700e082be3 | |
parent | 5df681db00cdc7dac638611f3fe76076290d78b2 (diff) | |
parent | cc9b3a20a7bee53eaf69cb34fa30f1329cbb081c (diff) | |
download | native-e31f6eb5c49e0e638585243ac36ce139b60a6fb1.tar.gz |
Merge cherrypicks of [4741663, 4741664, 4741665, 4741666, 4743080, 4743081, 4743082, 4743083, 4741262, 4741263, 4741264, 4741265, 4741266, 4741667, 4743084, 4741242, 4741243, 4741741, 4741742, 4741743, 4741744, 4741822, 4743085, 4741668, 4741338, 4743055, 4743056, 4743070, 4743073, 4743075, 4743076, 4743078, 4743079, 4743161, 4743162, 4743164, 4743165, 4743167, 4743168, 4743169, 4743170, 4741681, 4741682, 4741683, 4741684, 4741685, 4741686, 4741687, 4741688, 4741689, 4741690, 4741691, 4741692, 4741693, 4741694, 4741695, 4741696, 4741697, 4741698, 4741699, 4743240, 4743241, 4743242, 4743243, 4741745, 4741823, 4741824, 4741825, 4741267, 4741268, 4743244, 4743280, 4743281, 4743224, 4743203, 4743204, 4743205, 4741746, 4741747, 4743245, 4741826, 4741827, 4741828, 4741829, 4741748, 4741749, 4741750, 4743233, 4743282, 4741244, 4741245, 4741246, 4741247, 4743206, 4743207, 4743208, 4743209, 4743210, 4743211, 4743212, 4743213, 4743214, 4743215, 4743216, 4743217, 4743218, 4743219, 4743360, 4743361, 4743362, 4743363, 4743364, 4743365, 4743366, 4743367, 4743368, 4743369, 4743370, 4743371, 4743372, 4743373, 4743374, 4743375, 4743376, 4743377, 4743283, 4743284, 4741830, 4742501, 4743246, 4743086, 4743087, 4743378, 4743379, 4741751] into sparse-4749909-L04200000199131547android-8.1.0_r50android-8.1.0_r47android-8.1.0_r46oreo-m6-s4-release
Change-Id: Iead43bb0deac18379a0a05dff4cadc3a86e59d1b
-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; |