summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-06-04 23:56:33 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-06-04 23:56:33 +0000
commit09644e0962a71e430a2c346b54f4e233cf969904 (patch)
treefe4081a0bbd50570afdb060c0cda57b68f20a67c
parentdc5ac96ccfb3539f5a1b0ffb54b3e157dcf124f3 (diff)
parent8d78cae0d84042ac8129c2b7e8c80806a7c23ddb (diff)
downloadnative-oreo-m4-s9-release.tar.gz
Merge cherrypicks of [4252776, 4252777, 4252778, 4252779, 4253819, 4253820, 4256261, 4256262, 4254470, 4254471, 4256281, 4255145, 4255146, 4255252, 4255253, 4255254, 4255255, 4252780, 4255147, 4252862, 4256148, 4256149, 4256150, 4256151, 4256152, 4256153, 4256154, 4255256, 4255257, 4255258, 4255259, 4253843, 4253844, 4253845, 4253846, 4253847, 4253848, 4253849, 4256156, 4256269, 4256272, 4256273, 4256401, 4255338, 4255339, 4256422, 4256402, 4256157, 4256223, 4256224, 4256158, 4256159, 4256160, 4256441, 4256442, 4256443, 4256444, 4256445, 4256446, 4256447, 4256448, 4256449, 4256450, 4256451, 4254472, 4256285, 4256403, 4256274, 4256424, 4256452, 4256275, 4256276, 4255153, 4253850, 4253851, 4253852, 4253853, 4253854] into sparse-4732991-L34000000179248081android-8.1.0_r39oreo-m4-s9-release
Change-Id: Idedf026d57da0d4d092329143de43339a480ccac
-rw-r--r--libs/binder/Parcel.cpp89
-rw-r--r--libs/binder/include/binder/Parcel.h2
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;