diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-07-20 00:21:55 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-07-20 00:21:55 +0000 |
commit | fc1908fec8ebf1dc2467c3bd1ee6fa67bf23ce7b (patch) | |
tree | fe4081a0bbd50570afdb060c0cda57b68f20a67c | |
parent | dc5ac96ccfb3539f5a1b0ffb54b3e157dcf124f3 (diff) | |
parent | 1d7f3f04db43d3f7c684232bc840b3d1550c05d6 (diff) | |
download | native-oreo-m4-s11-release.tar.gz |
Merge cherrypicks of [4583929, 4582754, 4582755, 4582756, 4583930, 4583931, 4583932, 4586307, 4586953, 4582585, 4586964, 4586965, 4586984, 4586985, 4586986, 4586987, 4586966, 4582586, 4582885, 4586531, 4586532, 4586533, 4586535, 4586536, 4586537, 4586538, 4586539, 4586540, 4586541, 4586542, 4586890, 4586891, 4586892, 4586893, 4586894, 4586895, 4586896, 4586897, 4586898, 4586899, 4586900, 4586901, 4586902, 4586903, 4587104, 4587105, 4587106, 4586988, 4583933, 4583934, 4583935, 4586989, 4586990, 4587136, 4587138, 4586991, 4586308, 4586967, 4587069, 4587070, 4582886, 4582887, 4587164, 4582888, 4587027, 4587028, 4587029, 4587030, 4582587, 4582588, 4582589, 4582590, 4582591, 4582592, 4582593, 4582594, 4582595, 4582596, 4582597, 4582598, 4582599, 4582600, 4582601, 4582602, 4582603, 4587244, 4587245, 4587246, 4587247, 4587248, 4587249, 4587250, 4587251, 4587252, 4582760, 4583936, 4582761, 4586992, 4587229, 4587230, 4587231, 4587253, 4586968] into sparse-4732991-L37700000192334752android-8.1.0_r42oreo-m4-s11-release
Change-Id: I58122310c352a17945156810ec85728a445d291c
-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; |