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

Commit 1b488f0f authored by Steven Moreland's avatar Steven Moreland Committed by Automerger Merge Worker
Browse files

Merge "libbinder: service driver fuzzes nested ifaces" am: 9146157b am:...

Merge "libbinder: service driver fuzzes nested ifaces" am: 9146157b am: 14ef7816 am: 1846cc01 am: cdc0b0af

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/2039007

Change-Id: I6a596e00c566cd07f4202852bf6232daa8fc5ae8
parents 2663d6c0 cdc0b0af
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -569,6 +569,47 @@ bool Parcel::hasFileDescriptors() const
    return mHasFds;
}

std::vector<sp<IBinder>> Parcel::debugReadAllStrongBinders() const {
    std::vector<sp<IBinder>> ret;

    size_t initPosition = dataPosition();
    for (size_t i = 0; i < mObjectsSize; i++) {
        binder_size_t offset = mObjects[i];
        const flat_binder_object* flat =
                reinterpret_cast<const flat_binder_object*>(mData + offset);
        if (flat->hdr.type != BINDER_TYPE_BINDER) continue;

        setDataPosition(offset);

        sp<IBinder> binder = readStrongBinder();
        if (binder != nullptr) ret.push_back(binder);
    }

    setDataPosition(initPosition);
    return ret;
}

std::vector<int> Parcel::debugReadAllFileDescriptors() const {
    std::vector<int> ret;

    size_t initPosition = dataPosition();
    for (size_t i = 0; i < mObjectsSize; i++) {
        binder_size_t offset = mObjects[i];
        const flat_binder_object* flat =
                reinterpret_cast<const flat_binder_object*>(mData + offset);
        if (flat->hdr.type != BINDER_TYPE_FD) continue;

        setDataPosition(offset);

        int fd = readFileDescriptor();
        LOG_ALWAYS_FATAL_IF(fd == -1);
        ret.push_back(fd);
    }

    setDataPosition(initPosition);
    return ret;
}

status_t Parcel::hasFileDescriptorsInRange(size_t offset, size_t len, bool* result) const {
    if (len > INT32_MAX || offset > INT32_MAX) {
        // Don't accept size_t values which may have come from an inadvertent conversion from a
+6 −0
Original line number Diff line number Diff line
@@ -95,6 +95,12 @@ public:
    bool                hasFileDescriptors() const;
    status_t hasFileDescriptorsInRange(size_t offset, size_t length, bool* result) const;

    // returns all binder objects in the Parcel
    std::vector<sp<IBinder>> debugReadAllStrongBinders() const;
    // returns all file descriptors in the Parcel
    // does not dup
    std::vector<int> debugReadAllFileDescriptors() const;

    // Zeros data when reallocating. Other mitigations may be added
    // in the future.
    //
+37 −0
Original line number Diff line number Diff line
@@ -20,9 +20,12 @@
#include <cutils/ashmem.h>
#include <gtest/gtest.h>

using android::BBinder;
using android::IBinder;
using android::IPCThreadState;
using android::OK;
using android::Parcel;
using android::sp;
using android::status_t;
using android::String16;
using android::String8;
@@ -75,6 +78,40 @@ TEST(Parcel, EnforceNoDataAvail) {
    EXPECT_EQ(p.enforceNoDataAvail().exceptionCode(), Status::Exception::EX_NONE);
}

TEST(Parcel, DebugReadAllBinders) {
    sp<IBinder> binder1 = sp<BBinder>::make();
    sp<IBinder> binder2 = sp<BBinder>::make();

    Parcel p;
    p.writeInt32(4);
    p.writeStrongBinder(binder1);
    p.writeStrongBinder(nullptr);
    p.writeInt32(4);
    p.writeStrongBinder(binder2);
    p.writeInt32(4);

    auto ret = p.debugReadAllStrongBinders();

    ASSERT_EQ(ret.size(), 2);
    EXPECT_EQ(ret[0], binder1);
    EXPECT_EQ(ret[1], binder2);
}

TEST(Parcel, DebugReadAllFds) {
    Parcel p;
    p.writeInt32(4);
    p.writeFileDescriptor(STDOUT_FILENO, false /*takeOwnership*/);
    p.writeInt32(4);
    p.writeFileDescriptor(STDIN_FILENO, false /*takeOwnership*/);
    p.writeInt32(4);

    auto ret = p.debugReadAllFileDescriptors();

    ASSERT_EQ(ret.size(), 2);
    EXPECT_EQ(ret[0], STDOUT_FILENO);
    EXPECT_EQ(ret[1], STDIN_FILENO);
}

// Tests a second operation results in a parcel at the same location as it
// started.
void parcelOpSameLength(const std::function<void(Parcel*)>& a, const std::function<void(Parcel*)>& b) {
+2 −0
Original line number Diff line number Diff line
@@ -109,6 +109,8 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
    },
    PARCEL_READ_NO_STATUS(size_t, allowFds),
    PARCEL_READ_NO_STATUS(size_t, hasFileDescriptors),
    PARCEL_READ_NO_STATUS(std::vector<android::sp<android::IBinder>>, debugReadAllStrongBinders),
    PARCEL_READ_NO_STATUS(std::vector<int>, debugReadAllFileDescriptors),
    [] (const ::android::Parcel& p, uint8_t len) {
        std::string interface(len, 'a');
        FUZZ_LOG() << "about to enforceInterface: " << interface;
+3 −2
Original line number Diff line number Diff line
@@ -16,12 +16,13 @@

#pragma once

#include <android-base/unique_fd.h>
#include <fuzzer/FuzzedDataProvider.h>

namespace android {

// ownership to callee, always valid or aborts
// always valid or aborts
// get a random FD for use in fuzzing, of a few different specific types
int getRandomFd(FuzzedDataProvider* provider);
base::unique_fd getRandomFd(FuzzedDataProvider* provider);

} // namespace android
Loading