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

Commit a8021fc8 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Replay recorded fds and binders in fuzzers" into main

parents eee1cf5f 76b1815f
Loading
Loading
Loading
Loading
+47 −12
Original line number Diff line number Diff line
@@ -114,8 +114,8 @@ static_assert(PADDING8(8) == 0);

RecordedTransaction::RecordedTransaction(RecordedTransaction&& t) noexcept {
    mData = t.mData;
    mSent.setData(t.getDataParcel().data(), t.getDataParcel().dataSize());
    mReply.setData(t.getReplyParcel().data(), t.getReplyParcel().dataSize());
    mSentDataOnly.setData(t.getDataParcel().data(), t.getDataParcel().dataSize());
    mReplyDataOnly.setData(t.getReplyParcel().data(), t.getReplyParcel().dataSize());
}

std::optional<RecordedTransaction> RecordedTransaction::fromDetails(
@@ -136,12 +136,21 @@ std::optional<RecordedTransaction> RecordedTransaction::fromDetails(
        return std::nullopt;
    }

    if (t.mSent.setData(dataParcel.data(), dataParcel.dataBufferSize()) != android::NO_ERROR) {
    if (const auto* kernelFields = dataParcel.maybeKernelFields()) {
        for (size_t i = 0; i < kernelFields->mObjectsSize; i++) {
            uint64_t offset = kernelFields->mObjects[i];
            t.mData.mSentObjectData.push_back(offset);
        }
    }

    if (t.mSentDataOnly.setData(dataParcel.data(), dataParcel.dataBufferSize()) !=
        android::NO_ERROR) {
        ALOGE("Failed to set sent parcel data.");
        return std::nullopt;
    }

    if (t.mReply.setData(replyParcel.data(), replyParcel.dataBufferSize()) != android::NO_ERROR) {
    if (t.mReplyDataOnly.setData(replyParcel.data(), replyParcel.dataBufferSize()) !=
        android::NO_ERROR) {
        ALOGE("Failed to set reply parcel data.");
        return std::nullopt;
    }
@@ -154,6 +163,7 @@ enum {
    DATA_PARCEL_CHUNK = 2,
    REPLY_PARCEL_CHUNK = 3,
    INTERFACE_NAME_CHUNK = 4,
    DATA_PARCEL_OBJECT_CHUNK = 5,
    END_CHUNK = 0x00ffffff,
};

@@ -265,7 +275,7 @@ std::optional<RecordedTransaction> RecordedTransaction::fromFile(const unique_fd
                break;
            }
            case DATA_PARCEL_CHUNK: {
                if (t.mSent.setData(reinterpret_cast<const unsigned char*>(payloadMap),
                if (t.mSentDataOnly.setData(reinterpret_cast<const unsigned char*>(payloadMap),
                                            chunk.dataSize) != android::NO_ERROR) {
                    ALOGE("Failed to set sent parcel data.");
                    return std::nullopt;
@@ -273,13 +283,22 @@ std::optional<RecordedTransaction> RecordedTransaction::fromFile(const unique_fd
                break;
            }
            case REPLY_PARCEL_CHUNK: {
                if (t.mReply.setData(reinterpret_cast<const unsigned char*>(payloadMap),
                if (t.mReplyDataOnly.setData(reinterpret_cast<const unsigned char*>(payloadMap),
                                             chunk.dataSize) != android::NO_ERROR) {
                    ALOGE("Failed to set reply parcel data.");
                    return std::nullopt;
                }
                break;
            }
            case DATA_PARCEL_OBJECT_CHUNK: {
                const uint64_t* objects = reinterpret_cast<const uint64_t*>(payloadMap);
                size_t metaDataSize = (chunk.dataSize / sizeof(uint64_t));
                ALOGI("Total objects found in saved parcel %zu", metaDataSize);
                for (size_t index = 0; index < metaDataSize; ++index) {
                    t.mData.mSentObjectData.push_back(objects[index]);
                }
                break;
            }
            case END_CHUNK:
                break;
            default:
@@ -343,14 +362,26 @@ android::status_t RecordedTransaction::dumpToFile(const unique_fd& fd) const {
        return UNKNOWN_ERROR;
    }

    if (NO_ERROR != writeChunk(fd, DATA_PARCEL_CHUNK, mSent.dataBufferSize(), mSent.data())) {
    if (NO_ERROR !=
        writeChunk(fd, DATA_PARCEL_CHUNK, mSentDataOnly.dataBufferSize(), mSentDataOnly.data())) {
        ALOGE("Failed to write sent Parcel to fd %d", fd.get());
        return UNKNOWN_ERROR;
    }
    if (NO_ERROR != writeChunk(fd, REPLY_PARCEL_CHUNK, mReply.dataBufferSize(), mReply.data())) {

    if (NO_ERROR !=
        writeChunk(fd, REPLY_PARCEL_CHUNK, mReplyDataOnly.dataBufferSize(),
                   mReplyDataOnly.data())) {
        ALOGE("Failed to write reply Parcel to fd %d", fd.get());
        return UNKNOWN_ERROR;
    }

    if (NO_ERROR !=
        writeChunk(fd, DATA_PARCEL_OBJECT_CHUNK, mData.mSentObjectData.size() * sizeof(uint64_t),
                   reinterpret_cast<const uint8_t*>(mData.mSentObjectData.data()))) {
        ALOGE("Failed to write sent parcel object metadata to fd %d", fd.get());
        return UNKNOWN_ERROR;
    }

    if (NO_ERROR != writeChunk(fd, END_CHUNK, 0, NULL)) {
        ALOGE("Failed to write end chunk to fd %d", fd.get());
        return UNKNOWN_ERROR;
@@ -384,10 +415,14 @@ uint32_t RecordedTransaction::getVersion() const {
    return mData.mHeader.version;
}

const std::vector<uint64_t>& RecordedTransaction::getObjectOffsets() const {
    return mData.mSentObjectData;
}

const Parcel& RecordedTransaction::getDataParcel() const {
    return mSent;
    return mSentDataOnly;
}

const Parcel& RecordedTransaction::getReplyParcel() const {
    return mReply;
    return mReplyDataOnly;
}
+6 −0
Original line number Diff line number Diff line
@@ -55,6 +55,9 @@ class String8;
class TextOutput;
namespace binder {
class Status;
namespace debug {
class RecordedTransaction;
}
}

class Parcel {
@@ -1443,6 +1446,9 @@ private:
    // TODO(b/202029388): Remove 'getBlobAshmemSize' once no prebuilts reference
    // this
    size_t getBlobAshmemSize() const;

    // Needed so that we can save object metadata to the disk
    friend class android::binder::debug::RecordedTransaction;
};

// ---------------------------------------------------------------------------
+4 −2
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ public:
    uint32_t getVersion() const;
    const Parcel& getDataParcel() const;
    const Parcel& getReplyParcel() const;
    const std::vector<uint64_t>& getObjectOffsets() const;

private:
    RecordedTransaction() = default;
@@ -75,10 +76,11 @@ private:
    struct MovableData { // movable
        TransactionHeader mHeader;
        std::string mInterfaceName;
        std::vector<uint64_t> mSentObjectData; /* Object Offsets */
    };
    MovableData mData;
    Parcel mSent;
    Parcel mReply;
    Parcel mSentDataOnly;
    Parcel mReplyDataOnly;
};

} // namespace binder::debug
+7 −0
Original line number Diff line number Diff line
@@ -69,10 +69,14 @@ cc_test {
cc_test {
    name: "binderRecordReplayTest",
    srcs: ["binderRecordReplayTest.cpp"],
    cflags: [
        "-DBINDER_WITH_KERNEL_IPC",
    ],
    shared_libs: [
        "libbinder",
        "libcutils",
        "libutils",
        "liblog",
    ],
    static_libs: [
        "binderRecordReplayTestIface-cpp",
@@ -96,6 +100,9 @@ aidl_interface {
            enabled: true,
            platform_apis: true,
        },
        ndk: {
            enabled: false,
        },
    },
}

+6 −0
Original line number Diff line number Diff line
@@ -69,4 +69,10 @@ interface IBinderRecordReplayTest {

    void setSingleDataParcelableArray(in SingleDataParcelable[] input);
    SingleDataParcelable[] getSingleDataParcelableArray();

    void setBinder(in IBinder binder);
    IBinder getBinder();

    void setFileDescriptor(in FileDescriptor fd);
    FileDescriptor getFileDescriptor();
}
Loading