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

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

Merge "libbinder_ndk: read size checks" am: 663f9902

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

Change-Id: I439e2a53781149f7f2d8b436def1c7f171b632e3
parents cbc3d170 663f9902
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -910,6 +910,9 @@ static inline binder_status_t AParcel_resizeVector(const AParcel* parcel, std::v
    if (err != STATUS_OK) return err;
    if (err != STATUS_OK) return err;
    if (size < 0) return STATUS_UNEXPECTED_NULL;
    if (size < 0) return STATUS_UNEXPECTED_NULL;


    // TODO(b/188215728): delegate to libbinder_ndk
    if (size > 1000000) return STATUS_NO_MEMORY;

    vec->resize(static_cast<size_t>(size));
    vec->resize(static_cast<size_t>(size));
    return STATUS_OK;
    return STATUS_OK;
}
}
@@ -931,6 +934,9 @@ static inline binder_status_t AParcel_resizeVector(const AParcel* parcel,
        return STATUS_OK;
        return STATUS_OK;
    }
    }


    // TODO(b/188215728): delegate to libbinder_ndk
    if (size > 1000000) return STATUS_NO_MEMORY;

    *vec = std::optional<std::vector<T>>(std::vector<T>{});
    *vec = std::optional<std::vector<T>>(std::vector<T>{});
    (*vec)->resize(static_cast<size_t>(size));
    (*vec)->resize(static_cast<size_t>(size));
    return STATUS_OK;
    return STATUS_OK;
+32 −28
Original line number Original line Diff line number Diff line
@@ -46,7 +46,8 @@ using ArrayGetter = T (*)(const void* arrayData, size_t index);
template <typename T>
template <typename T>
using ArraySetter = void (*)(void* arrayData, size_t index, T value);
using ArraySetter = void (*)(void* arrayData, size_t index, T value);


binder_status_t WriteAndValidateArraySize(AParcel* parcel, bool isNullArray, int32_t length) {
static binder_status_t WriteAndValidateArraySize(AParcel* parcel, bool isNullArray,
                                                 int32_t length) {
    // only -1 can be used to represent a null array
    // only -1 can be used to represent a null array
    if (length < -1) return STATUS_BAD_VALUE;
    if (length < -1) return STATUS_BAD_VALUE;


@@ -61,12 +62,24 @@ binder_status_t WriteAndValidateArraySize(AParcel* parcel, bool isNullArray, int


    Parcel* rawParcel = parcel->get();
    Parcel* rawParcel = parcel->get();


    status_t status = rawParcel->writeInt32(static_cast<int32_t>(length));
    status_t status = rawParcel->writeInt32(length);
    if (status != STATUS_OK) return PruneStatusT(status);
    if (status != STATUS_OK) return PruneStatusT(status);


    return STATUS_OK;
    return STATUS_OK;
}
}


static binder_status_t ReadAndValidateArraySize(const AParcel* parcel, int32_t* length) {
    if (status_t status = parcel->get()->readInt32(length); status != STATUS_OK) {
        return PruneStatusT(status);
    }

    if (*length < -1) return STATUS_BAD_VALUE;  // libbinder_ndk reserves these
    if (*length <= 0) return STATUS_OK;         // null
    if (static_cast<size_t>(*length) > parcel->get()->dataAvail()) return STATUS_NO_MEMORY;

    return STATUS_OK;
}

template <typename T>
template <typename T>
binder_status_t WriteArray(AParcel* parcel, const T* array, int32_t length) {
binder_status_t WriteArray(AParcel* parcel, const T* array, int32_t length) {
    binder_status_t status = WriteAndValidateArraySize(parcel, array == nullptr, length);
    binder_status_t status = WriteAndValidateArraySize(parcel, array == nullptr, length);
@@ -111,10 +124,9 @@ binder_status_t ReadArray(const AParcel* parcel, void* arrayData,
    const Parcel* rawParcel = parcel->get();
    const Parcel* rawParcel = parcel->get();


    int32_t length;
    int32_t length;
    status_t status = rawParcel->readInt32(&length);
    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {

        return status;
    if (status != STATUS_OK) return PruneStatusT(status);
    }
    if (length < -1) return STATUS_BAD_VALUE;


    T* array;
    T* array;
    if (!allocator(arrayData, length, &array)) return STATUS_NO_MEMORY;
    if (!allocator(arrayData, length, &array)) return STATUS_NO_MEMORY;
@@ -140,10 +152,9 @@ binder_status_t ReadArray<char16_t>(const AParcel* parcel, void* arrayData,
    const Parcel* rawParcel = parcel->get();
    const Parcel* rawParcel = parcel->get();


    int32_t length;
    int32_t length;
    status_t status = rawParcel->readInt32(&length);
    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {

        return status;
    if (status != STATUS_OK) return PruneStatusT(status);
    }
    if (length < -1) return STATUS_BAD_VALUE;


    char16_t* array;
    char16_t* array;
    if (!allocator(arrayData, length, &array)) return STATUS_NO_MEMORY;
    if (!allocator(arrayData, length, &array)) return STATUS_NO_MEMORY;
@@ -155,7 +166,7 @@ binder_status_t ReadArray<char16_t>(const AParcel* parcel, void* arrayData,
    if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
    if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;


    for (int32_t i = 0; i < length; i++) {
    for (int32_t i = 0; i < length; i++) {
        status = rawParcel->readChar(array + i);
        status_t status = rawParcel->readChar(array + i);


        if (status != STATUS_OK) return PruneStatusT(status);
        if (status != STATUS_OK) return PruneStatusT(status);
    }
    }
@@ -189,10 +200,9 @@ binder_status_t ReadArray(const AParcel* parcel, void* arrayData, ArrayAllocator
    const Parcel* rawParcel = parcel->get();
    const Parcel* rawParcel = parcel->get();


    int32_t length;
    int32_t length;
    status_t status = rawParcel->readInt32(&length);
    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {

        return status;
    if (status != STATUS_OK) return PruneStatusT(status);
    }
    if (length < -1) return STATUS_BAD_VALUE;


    if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
    if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;


@@ -200,7 +210,7 @@ binder_status_t ReadArray(const AParcel* parcel, void* arrayData, ArrayAllocator


    for (int32_t i = 0; i < length; i++) {
    for (int32_t i = 0; i < length; i++) {
        T readTarget;
        T readTarget;
        status = (rawParcel->*read)(&readTarget);
        status_t status = (rawParcel->*read)(&readTarget);
        if (status != STATUS_OK) return PruneStatusT(status);
        if (status != STATUS_OK) return PruneStatusT(status);


        setter(arrayData, i, readTarget);
        setter(arrayData, i, readTarget);
@@ -402,13 +412,10 @@ struct StringArrayElementAllocationAdapter {
binder_status_t AParcel_readStringArray(const AParcel* parcel, void* arrayData,
binder_status_t AParcel_readStringArray(const AParcel* parcel, void* arrayData,
                                        AParcel_stringArrayAllocator allocator,
                                        AParcel_stringArrayAllocator allocator,
                                        AParcel_stringArrayElementAllocator elementAllocator) {
                                        AParcel_stringArrayElementAllocator elementAllocator) {
    const Parcel* rawParcel = parcel->get();

    int32_t length;
    int32_t length;
    status_t status = rawParcel->readInt32(&length);
    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {

        return status;
    if (status != STATUS_OK) return PruneStatusT(status);
    }
    if (length < -1) return STATUS_BAD_VALUE;


    if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
    if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;


@@ -449,13 +456,10 @@ binder_status_t AParcel_writeParcelableArray(AParcel* parcel, const void* arrayD
binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
                                            AParcel_parcelableArrayAllocator allocator,
                                            AParcel_parcelableArrayAllocator allocator,
                                            AParcel_readParcelableElement elementReader) {
                                            AParcel_readParcelableElement elementReader) {
    const Parcel* rawParcel = parcel->get();

    int32_t length;
    int32_t length;
    status_t status = rawParcel->readInt32(&length);
    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {

        return status;
    if (status != STATUS_OK) return PruneStatusT(status);
    }
    if (length < -1) return STATUS_BAD_VALUE;


    if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
    if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;


+22 −23
Original line number Original line Diff line number Diff line
@@ -91,28 +91,27 @@ std::vector<ParcelRead<NdkParcelAdapter>> BINDER_NDK_PARCEL_READ_FUNCTIONS{
        PARCEL_READ(ndk::ScopedFileDescriptor, ndk::AParcel_readRequiredParcelFileDescriptor),
        PARCEL_READ(ndk::ScopedFileDescriptor, ndk::AParcel_readRequiredParcelFileDescriptor),
        PARCEL_READ(std::string, ndk::AParcel_readString),
        PARCEL_READ(std::string, ndk::AParcel_readString),
        PARCEL_READ(std::optional<std::string>, ndk::AParcel_readString),
        PARCEL_READ(std::optional<std::string>, ndk::AParcel_readString),
        // TODO(b/131868573): can force process to allocate arbitrary amount of

        // memory
        PARCEL_READ(std::vector<std::string>, ndk::AParcel_readVector),
        // PARCEL_READ(std::vector<std::string>, ndk::AParcel_readVector),
        PARCEL_READ(std::optional<std::vector<std::optional<std::string>>>, ndk::AParcel_readVector),
        // PARCEL_READ(std::optional<std::vector<std::optional<std::string>>>,
        PARCEL_READ(std::vector<SomeParcelable>, ndk::AParcel_readVector),
        // ndk::AParcel_readVector), PARCEL_READ(std::vector<SomeParcelable>,
        PARCEL_READ(std::vector<int32_t>, ndk::AParcel_readVector),
        // ndk::AParcel_readVector), PARCEL_READ(std::vector<int32_t>, ndk::AParcel_readVector),
        PARCEL_READ(std::optional<std::vector<int32_t>>, ndk::AParcel_readVector),
        // PARCEL_READ(std::optional<std::vector<int32_t>>, ndk::AParcel_readVector),
        PARCEL_READ(std::vector<uint32_t>, ndk::AParcel_readVector),
        // PARCEL_READ(std::vector<uint32_t>, ndk::AParcel_readVector),
        PARCEL_READ(std::optional<std::vector<uint32_t>>, ndk::AParcel_readVector),
        // PARCEL_READ(std::optional<std::vector<uint32_t>>, ndk::AParcel_readVector),
        PARCEL_READ(std::vector<int64_t>, ndk::AParcel_readVector),
        // PARCEL_READ(std::vector<int64_t>, ndk::AParcel_readVector),
        PARCEL_READ(std::optional<std::vector<int64_t>>, ndk::AParcel_readVector),
        // PARCEL_READ(std::optional<std::vector<int64_t>>, ndk::AParcel_readVector),
        PARCEL_READ(std::vector<uint64_t>, ndk::AParcel_readVector),
        // PARCEL_READ(std::vector<uint64_t>, ndk::AParcel_readVector),
        PARCEL_READ(std::optional<std::vector<uint64_t>>, ndk::AParcel_readVector),
        // PARCEL_READ(std::optional<std::vector<uint64_t>>, ndk::AParcel_readVector),
        PARCEL_READ(std::vector<float>, ndk::AParcel_readVector),
        // PARCEL_READ(std::vector<float>, ndk::AParcel_readVector),
        PARCEL_READ(std::optional<std::vector<float>>, ndk::AParcel_readVector),
        // PARCEL_READ(std::optional<std::vector<float>>, ndk::AParcel_readVector),
        PARCEL_READ(std::vector<double>, ndk::AParcel_readVector),
        // PARCEL_READ(std::vector<double>, ndk::AParcel_readVector),
        PARCEL_READ(std::optional<std::vector<double>>, ndk::AParcel_readVector),
        // PARCEL_READ(std::optional<std::vector<double>>, ndk::AParcel_readVector),
        PARCEL_READ(std::vector<bool>, ndk::AParcel_readVector),
        // PARCEL_READ(std::vector<bool>, ndk::AParcel_readVector),
        PARCEL_READ(std::optional<std::vector<bool>>, ndk::AParcel_readVector),
        // PARCEL_READ(std::optional<std::vector<bool>>, ndk::AParcel_readVector),
        PARCEL_READ(std::vector<char16_t>, ndk::AParcel_readVector),
        // PARCEL_READ(std::vector<char16_t>, ndk::AParcel_readVector),
        PARCEL_READ(std::optional<std::vector<char16_t>>, ndk::AParcel_readVector),
        // PARCEL_READ(std::optional<std::vector<char16_t>>, ndk::AParcel_readVector),
        PARCEL_READ(std::vector<int32_t>, ndk::AParcel_resizeVector),
        // PARCEL_READ(std::vector<int32_t>, ndk::AParcel_resizeVector),
        PARCEL_READ(std::optional<std::vector<int32_t>>, ndk::AParcel_resizeVector),
        // PARCEL_READ(std::optional<std::vector<int32_t>>, ndk::AParcel_resizeVector),
};
};
// clang-format on
// clang-format on