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

Commit 694e9732 authored by Frederick Mayle's avatar Frederick Mayle
Browse files

libbinder: Validate the RPC object positions immediately

We already check the bounds when they are used, but it is easier to
reason about the code if they are validated before being stored.

The `freeData` call was redundant (handled by dtor).

Test: TH
Change-Id: I5160e72b5225b933068a3aa68eb5287bf7a29af1
parent 53b6ffe5
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -2590,6 +2590,22 @@ status_t Parcel::rpcSetDataReference(

    LOG_ALWAYS_FATAL_IF(session == nullptr);

    if (objectTableSize != ancillaryFds.size()) {
        ALOGE("objectTableSize=%zu ancillaryFds.size=%zu", objectTableSize, ancillaryFds.size());
        relFunc(data, dataSize, nullptr, 0);
        return BAD_VALUE;
    }
    for (size_t i = 0; i < objectTableSize; i++) {
        uint32_t minObjectEnd;
        if (__builtin_add_overflow(objectTable[i], sizeof(RpcFields::ObjectType), &minObjectEnd) ||
            minObjectEnd >= dataSize) {
            ALOGE("received out of range object position: %" PRIu32 " (parcel size is %zu)",
                  objectTable[i], dataSize);
            relFunc(data, dataSize, nullptr, 0);
            return BAD_VALUE;
        }
    }

    freeData();
    markForRpc(session);

@@ -2600,12 +2616,6 @@ status_t Parcel::rpcSetDataReference(
    mDataSize = mDataCapacity = dataSize;
    mOwner = relFunc;

    if (objectTableSize != ancillaryFds.size()) {
        ALOGE("objectTableSize=%zu ancillaryFds.size=%zu", objectTableSize, ancillaryFds.size());
        freeData(); // don't leak mData
        return BAD_VALUE;
    }

    rpcFields->mObjectPositions.reserve(objectTableSize);
    for (size_t i = 0; i < objectTableSize; i++) {
        rpcFields->mObjectPositions.push_back(objectTable[i]);