Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61f77509 authored by Michael Wachenschwanz's avatar Michael Wachenschwanz Committed by android-build-merger
Browse files

Disallow reading object data from Parcels with non-object reads am: c517681c am: e69532fd

am: c720d6e2

Change-Id: I816f84ad3ba3b1089e2b7df4945f8e57d5ba5dde
parents 64fc7a4b c720d6e2
Loading
Loading
Loading
Loading
+73 −0
Original line number Original line Diff line number Diff line
@@ -433,6 +433,7 @@ void Parcel::setDataPosition(size_t pos) const


    mDataPos = pos;
    mDataPos = pos;
    mNextObjectHint = 0;
    mNextObjectHint = 0;
    mObjectsSorted = false;
}
}


status_t Parcel::setDataCapacity(size_t size)
status_t Parcel::setDataCapacity(size_t size)
@@ -1469,6 +1470,59 @@ void Parcel::remove(size_t /*start*/, size_t /*amt*/)
    LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
    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
status_t Parcel::read(void* outData, size_t len) const
{
{
    if (len > INT32_MAX) {
    if (len > INT32_MAX) {
@@ -1479,6 +1533,10 @@ status_t Parcel::read(void* outData, size_t len) const


    if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
    if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
            && len <= pad_size(len)) {
            && len <= pad_size(len)) {
        if (mObjectsSize > 0) {
            status_t err = validateReadData(mDataPos + pad_size(len));
            if(err != NO_ERROR) return err;
        }
        memcpy(outData, mData+mDataPos, len);
        memcpy(outData, mData+mDataPos, len);
        mDataPos += pad_size(len);
        mDataPos += pad_size(len);
        ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
        ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
@@ -1497,6 +1555,11 @@ const void* Parcel::readInplace(size_t len) const


    if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
    if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
            && len <= pad_size(len)) {
            && len <= pad_size(len)) {
        if (mObjectsSize > 0) {
            status_t err = validateReadData(mDataPos + pad_size(len));
            if(err != NO_ERROR) return NULL;
        }

        const void* data = mData+mDataPos;
        const void* data = mData+mDataPos;
        mDataPos += pad_size(len);
        mDataPos += pad_size(len);
        ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
        ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
@@ -1510,6 +1573,11 @@ status_t Parcel::readAligned(T *pArg) const {
    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));


    if ((mDataPos+sizeof(T)) <= mDataSize) {
    if ((mDataPos+sizeof(T)) <= mDataSize) {
        if (mObjectsSize > 0) {
            status_t err = validateReadData(mDataPos + sizeof(T));
            if(err != NO_ERROR) return err;
        }

        const void* data = mData+mDataPos;
        const void* data = mData+mDataPos;
        mDataPos += sizeof(T);
        mDataPos += sizeof(T);
        *pArg =  *reinterpret_cast<const T*>(data);
        *pArg =  *reinterpret_cast<const T*>(data);
@@ -2366,6 +2434,7 @@ void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
    mObjects = const_cast<binder_size_t*>(objects);
    mObjects = const_cast<binder_size_t*>(objects);
    mObjectsSize = mObjectsCapacity = objectsCount;
    mObjectsSize = mObjectsCapacity = objectsCount;
    mNextObjectHint = 0;
    mNextObjectHint = 0;
    mObjectsSorted = false;
    mOwner = relFunc;
    mOwner = relFunc;
    mOwnerCookie = relCookie;
    mOwnerCookie = relCookie;
    for (size_t i = 0; i < mObjectsSize; i++) {
    for (size_t i = 0; i < mObjectsSize; i++) {
@@ -2524,6 +2593,7 @@ status_t Parcel::restartWrite(size_t desired)
    mObjects = NULL;
    mObjects = NULL;
    mObjectsSize = mObjectsCapacity = 0;
    mObjectsSize = mObjectsCapacity = 0;
    mNextObjectHint = 0;
    mNextObjectHint = 0;
    mObjectsSorted = false;
    mHasFds = false;
    mHasFds = false;
    mFdsKnown = true;
    mFdsKnown = true;
    mAllowFds = true;
    mAllowFds = true;
@@ -2610,6 +2680,7 @@ status_t Parcel::continueWrite(size_t desired)
        mDataCapacity = desired;
        mDataCapacity = desired;
        mObjectsSize = mObjectsCapacity = objectsSize;
        mObjectsSize = mObjectsCapacity = objectsSize;
        mNextObjectHint = 0;
        mNextObjectHint = 0;
        mObjectsSorted = false;


    } else if (mData) {
    } else if (mData) {
        if (objectsSize < mObjectsSize) {
        if (objectsSize < mObjectsSize) {
@@ -2631,6 +2702,7 @@ status_t Parcel::continueWrite(size_t desired)
            }
            }
            mObjectsSize = objectsSize;
            mObjectsSize = objectsSize;
            mNextObjectHint = 0;
            mNextObjectHint = 0;
            mObjectsSorted = false;
        }
        }


        // We own the data, so we can just do a realloc().
        // We own the data, so we can just do a realloc().
@@ -2703,6 +2775,7 @@ void Parcel::initState()
    mObjectsSize = 0;
    mObjectsSize = 0;
    mObjectsCapacity = 0;
    mObjectsCapacity = 0;
    mNextObjectHint = 0;
    mNextObjectHint = 0;
    mObjectsSorted = false;
    mHasFds = false;
    mHasFds = false;
    mFdsKnown = true;
    mFdsKnown = true;
    mAllowFds = true;
    mAllowFds = true;
+2 −0
Original line number Original line Diff line number Diff line
@@ -417,6 +417,7 @@ private:
    void                freeDataNoInit();
    void                freeDataNoInit();
    void                initState();
    void                initState();
    void                scanForFds() const;
    void                scanForFds() const;
    status_t            validateReadData(size_t len) const;
                        
                        
    template<class T>
    template<class T>
    status_t            readAligned(T *pArg) const;
    status_t            readAligned(T *pArg) const;
@@ -463,6 +464,7 @@ private:
    size_t              mObjectsSize;
    size_t              mObjectsSize;
    size_t              mObjectsCapacity;
    size_t              mObjectsCapacity;
    mutable size_t      mNextObjectHint;
    mutable size_t      mNextObjectHint;
    mutable bool        mObjectsSorted;


    mutable bool        mFdsKnown;
    mutable bool        mFdsKnown;
    mutable bool        mHasFds;
    mutable bool        mHasFds;