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

Commit f110de51 authored by Steven Moreland's avatar Steven Moreland Committed by Gerrit Code Review
Browse files

Merge changes I17399680,I4952b3ab,I743b6227

* changes:
  service fuzzer: ignore interface checks
  Parcel: service fuzzing mode
  libbinder_driver: never enforce data avail
parents 38b89eae e99d8821
Loading
Loading
Loading
Loading
+47 −14
Original line number Diff line number Diff line
@@ -947,7 +947,10 @@ bool Parcel::enforceInterface(const char16_t* interface,
        threadState->setCallingWorkSourceUidWithoutPropagation(workSource);
        // vendor header
        int32_t header = readInt32();
        if (header != kHeader) {

        // fuzzers skip this check, because it is for protecting the underlying ABI, but
        // we don't want it to reduce our coverage
        if (header != kHeader && !mServiceFuzzing) {
            ALOGE("Expecting header 0x%x but found 0x%x. Mixing copies of libbinder?", kHeader,
                  header);
            return false;
@@ -965,6 +968,13 @@ bool Parcel::enforceInterface(const char16_t* interface,
    if (len == parcel_interface_len &&
            (!len || !memcmp(parcel_interface, interface, len * sizeof (char16_t)))) {
        return true;
    } else {
        if (mServiceFuzzing) {
            // ignore. Theoretically, this could cause a few false positives, because
            // people could assume things about getInterfaceDescriptor if they pass
            // this point, but it would be extremely fragile. It's more important that
            // we fuzz with the above things read from the Parcel.
            return true;
        } else {
            ALOGW("**** enforceInterface() expected '%s' but read '%s'",
                  String8(interface, len).string(),
@@ -972,11 +982,16 @@ bool Parcel::enforceInterface(const char16_t* interface,
            return false;
        }
    }
}

void Parcel::setEnforceNoDataAvail(bool enforceNoDataAvail) {
    mEnforceNoDataAvail = enforceNoDataAvail;
}

void Parcel::setServiceFuzzing() {
    mServiceFuzzing = true;
}

binder::Status Parcel::enforceNoDataAvail() const {
    if (!mEnforceNoDataAvail) {
        return binder::Status::ok();
@@ -1722,7 +1737,9 @@ status_t Parcel::validateReadData(size_t upperBound) const
            do {
                if (mDataPos < kernelFields->mObjects[nextObject] + sizeof(flat_binder_object)) {
                    // Requested info overlaps with an object
                    if (!mServiceFuzzing) {
                        ALOGE("Attempt to read from protected data in Parcel %p", this);
                    }
                    return PERMISSION_DENIED;
                }
                nextObject++;
@@ -2092,7 +2109,11 @@ String8 Parcel::readString8() const
    size_t len;
    const char* str = readString8Inplace(&len);
    if (str) return String8(str, len);

    if (!mServiceFuzzing) {
        ALOGE("Reading a NULL string not supported here.");
    }

    return String8();
}

@@ -2132,7 +2153,11 @@ String16 Parcel::readString16() const
    size_t len;
    const char16_t* str = readString16Inplace(&len);
    if (str) return String16(str, len);

    if (!mServiceFuzzing) {
        ALOGE("Reading a NULL string not supported here.");
    }

    return String16();
}

@@ -2172,7 +2197,9 @@ status_t Parcel::readStrongBinder(sp<IBinder>* val) const
{
    status_t status = readNullableStrongBinder(val);
    if (status == OK && !val->get()) {
        if (!mServiceFuzzing) {
            ALOGW("Expecting binder but got null!");
        }
        status = UNEXPECTED_NULL;
    }
    return status;
@@ -2237,9 +2264,11 @@ int Parcel::readFileDescriptor() const {
    if (const auto* rpcFields = maybeRpcFields()) {
        if (!std::binary_search(rpcFields->mObjectPositions.begin(),
                                rpcFields->mObjectPositions.end(), mDataPos)) {
            ALOGW("Attempt to read file descriptor from Parcel %p at offset %zu that is not in the "
                  "object list",
            if (!mServiceFuzzing) {
                ALOGW("Attempt to read file descriptor from Parcel %p at offset %zu that is not in "
                      "the object list",
                      this, mDataPos);
            }
            return BAD_TYPE;
        }

@@ -2497,9 +2526,12 @@ const flat_binder_object* Parcel::readObject(bool nullMetaData) const
                return obj;
            }
        }
        ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
        if (!mServiceFuzzing) {
            ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object "
                  "list",
                  this, DPOS);
        }
    }
    return nullptr;
}
#endif // BINDER_WITH_KERNEL_IPC
@@ -3093,6 +3125,7 @@ void Parcel::initState()
    mDeallocZero = false;
    mOwner = nullptr;
    mEnforceNoDataAvail = true;
    mServiceFuzzing = false;
}

void Parcel::scanForFds() const {
+5 −0
Original line number Diff line number Diff line
@@ -149,6 +149,10 @@ public:
    // This Api is used by fuzzers to skip dataAvail checks.
    void setEnforceNoDataAvail(bool enforceNoDataAvail);

    // When fuzzing, we want to remove certain ABI checks that cause significant
    // lost coverage, and we also want to avoid logs that cost too much to write.
    void setServiceFuzzing();

    void                freeData();

    size_t              objectsCount() const;
@@ -1330,6 +1334,7 @@ private:

    // Set this to false to skip dataAvail checks.
    bool mEnforceNoDataAvail;
    bool mServiceFuzzing;

    release_func        mOwner;

+4 −2
Original line number Diff line number Diff line
@@ -52,7 +52,8 @@ void fuzzService(const std::vector<sp<IBinder>>& binders, FuzzedDataProvider&& p
                    uint32_t flags = provider.ConsumeIntegral<uint32_t>();
                    Parcel data;
                    // for increased fuzz coverage
                    data.setEnforceNoDataAvail(provider.ConsumeBool());
                    data.setEnforceNoDataAvail(false);
                    data.setServiceFuzzing();

                    sp<IBinder> target = options.extraBinders.at(
                            provider.ConsumeIntegralInRange<size_t>(0,
@@ -73,7 +74,8 @@ void fuzzService(const std::vector<sp<IBinder>>& binders, FuzzedDataProvider&& p

                    Parcel reply;
                    // for increased fuzz coverage
                    reply.setEnforceNoDataAvail(provider.ConsumeBool());
                    reply.setEnforceNoDataAvail(false);
                    reply.setServiceFuzzing();
                    (void)target->transact(code, data, &reply, flags);

                    // feed back in binders and fds that are returned from the service, so that