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

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

Merge "libbinder: resizeOutVector size check" am: 895546f5

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

Change-Id: Ie3c6f8a03431e84f276ca419a7a0b6731ec850a2
parents 6612680f 895546f5
Loading
Loading
Loading
Loading
+23 −0
Original line number Original line Diff line number Diff line
@@ -1466,6 +1466,29 @@ const void* Parcel::readInplace(size_t len) const
    return nullptr;
    return nullptr;
}
}


status_t Parcel::readOutVectorSizeWithCheck(size_t elmSize, int32_t* size) const {
    if (status_t status = readInt32(size); status != OK) return status;
    if (*size < 0) return OK; // may be null, client to handle

    LOG_ALWAYS_FATAL_IF(elmSize > INT32_MAX, "Cannot have element as big as %zu", elmSize);

    // approximation, can't know max element size (e.g. if it makes heap
    // allocations)
    static_assert(sizeof(int) == sizeof(int32_t), "Android is LP64");
    int32_t allocationSize;
    if (__builtin_smul_overflow(elmSize, *size, &allocationSize)) return NO_MEMORY;

    // High limit of 1MB since something this big could never be returned. Could
    // probably scope this down, but might impact very specific usecases.
    constexpr int32_t kMaxAllocationSize = 1 * 1000 * 1000;

    if (allocationSize >= kMaxAllocationSize) {
        return NO_MEMORY;
    }

    return OK;
}

template<class T>
template<class T>
status_t Parcel::readAligned(T *pArg) const {
status_t Parcel::readAligned(T *pArg) const {
    static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
    static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
+5 −3
Original line number Original line Diff line number Diff line
@@ -561,6 +561,8 @@ private:
    status_t            flattenBinder(const sp<IBinder>& binder);
    status_t            flattenBinder(const sp<IBinder>& binder);
    status_t            unflattenBinder(sp<IBinder>* out) const;
    status_t            unflattenBinder(sp<IBinder>* out) const;


    status_t readOutVectorSizeWithCheck(size_t elmSize, int32_t* size) const;

    template<class T>
    template<class T>
    status_t            readAligned(T *pArg) const;
    status_t            readAligned(T *pArg) const;


@@ -1315,7 +1317,7 @@ status_t Parcel::writeVectorSize(const std::unique_ptr<std::vector<T>>& val) {
template<typename T>
template<typename T>
status_t Parcel::resizeOutVector(std::vector<T>* val) const {
status_t Parcel::resizeOutVector(std::vector<T>* val) const {
    int32_t size;
    int32_t size;
    status_t err = readInt32(&size);
    status_t err = readOutVectorSizeWithCheck(sizeof(T), &size);
    if (err != NO_ERROR) {
    if (err != NO_ERROR) {
        return err;
        return err;
    }
    }
@@ -1330,7 +1332,7 @@ status_t Parcel::resizeOutVector(std::vector<T>* val) const {
template<typename T>
template<typename T>
status_t Parcel::resizeOutVector(std::optional<std::vector<T>>* val) const {
status_t Parcel::resizeOutVector(std::optional<std::vector<T>>* val) const {
    int32_t size;
    int32_t size;
    status_t err = readInt32(&size);
    status_t err = readOutVectorSizeWithCheck(sizeof(T), &size);
    if (err != NO_ERROR) {
    if (err != NO_ERROR) {
        return err;
        return err;
    }
    }
@@ -1346,7 +1348,7 @@ status_t Parcel::resizeOutVector(std::optional<std::vector<T>>* val) const {
template<typename T>
template<typename T>
status_t Parcel::resizeOutVector(std::unique_ptr<std::vector<T>>* val) const {
status_t Parcel::resizeOutVector(std::unique_ptr<std::vector<T>>* val) const {
    int32_t size;
    int32_t size;
    status_t err = readInt32(&size);
    status_t err = readOutVectorSizeWithCheck(sizeof(T), &size);
    if (err != NO_ERROR) {
    if (err != NO_ERROR) {
        return err;
        return err;
    }
    }
+10 −2
Original line number Original line Diff line number Diff line
@@ -66,6 +66,10 @@ struct ExampleLightFlattenable : public android::LightFlattenablePod<ExampleLigh
    int32_t mValue = 0;
    int32_t mValue = 0;
};
};


struct BigStruct {
    uint8_t data[1337];
};

#define PARCEL_READ_WITH_STATUS(T, FUN) \
#define PARCEL_READ_WITH_STATUS(T, FUN) \
    [] (const ::android::Parcel& p, uint8_t /*data*/) {\
    [] (const ::android::Parcel& p, uint8_t /*data*/) {\
        FUZZ_LOG() << "about to read " #T " using " #FUN " with status";\
        FUZZ_LOG() << "about to read " #T " using " #FUN " with status";\
@@ -231,8 +235,12 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
        FUZZ_LOG() << "read lite flattenable: " << status;
        FUZZ_LOG() << "read lite flattenable: " << status;
    },
    },


    // TODO(b/131868573): can force read of arbitrarily sized vector
    PARCEL_READ_WITH_STATUS(std::vector<uint8_t>, resizeOutVector),
    // TODO: resizeOutVector
    PARCEL_READ_WITH_STATUS(std::optional<std::vector<uint8_t>>, resizeOutVector),
    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<uint8_t>>, resizeOutVector),
    PARCEL_READ_WITH_STATUS(std::vector<BigStruct>, resizeOutVector),
    PARCEL_READ_WITH_STATUS(std::optional<std::vector<BigStruct>>, resizeOutVector),
    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<BigStruct>>, resizeOutVector),


    PARCEL_READ_NO_STATUS(int32_t, readExceptionCode),
    PARCEL_READ_NO_STATUS(int32_t, readExceptionCode),
    [] (const android::Parcel& p, uint8_t /*len*/) {
    [] (const android::Parcel& p, uint8_t /*len*/) {