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

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

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

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

Change-Id: Id5e46474b6dfa0feec8c1b47879e8dcf0301092f
parents 9e7bd932 f31941bb
Loading
Loading
Loading
Loading
+6 −0
Original line number 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 (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));
    return STATUS_OK;
}
@@ -931,6 +934,9 @@ static inline binder_status_t AParcel_resizeVector(const AParcel* parcel,
        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)->resize(static_cast<size_t>(size));
    return STATUS_OK;
+32 −28
Original line number Diff line number Diff line
@@ -46,7 +46,8 @@ using ArrayGetter = T (*)(const void* arrayData, size_t index);
template <typename T>
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
    if (length < -1) return STATUS_BAD_VALUE;

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

    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);

    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>
binder_status_t WriteArray(AParcel* parcel, const T* array, int32_t 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();

    int32_t length;
    status_t status = rawParcel->readInt32(&length);

    if (status != STATUS_OK) return PruneStatusT(status);
    if (length < -1) return STATUS_BAD_VALUE;
    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
        return status;
    }

    T* array;
    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();

    int32_t length;
    status_t status = rawParcel->readInt32(&length);

    if (status != STATUS_OK) return PruneStatusT(status);
    if (length < -1) return STATUS_BAD_VALUE;
    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
        return status;
    }

    char16_t* array;
    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;

    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);
    }
@@ -189,10 +200,9 @@ binder_status_t ReadArray(const AParcel* parcel, void* arrayData, ArrayAllocator
    const Parcel* rawParcel = parcel->get();

    int32_t length;
    status_t status = rawParcel->readInt32(&length);

    if (status != STATUS_OK) return PruneStatusT(status);
    if (length < -1) return STATUS_BAD_VALUE;
    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
        return status;
    }

    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++) {
        T readTarget;
        status = (rawParcel->*read)(&readTarget);
        status_t status = (rawParcel->*read)(&readTarget);
        if (status != STATUS_OK) return PruneStatusT(status);

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

    int32_t length;
    status_t status = rawParcel->readInt32(&length);

    if (status != STATUS_OK) return PruneStatusT(status);
    if (length < -1) return STATUS_BAD_VALUE;
    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
        return status;
    }

    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,
                                            AParcel_parcelableArrayAllocator allocator,
                                            AParcel_readParcelableElement elementReader) {
    const Parcel* rawParcel = parcel->get();

    int32_t length;
    status_t status = rawParcel->readInt32(&length);

    if (status != STATUS_OK) return PruneStatusT(status);
    if (length < -1) return STATUS_BAD_VALUE;
    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
        return status;
    }

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

+22 −23
Original line number 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(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::optional<std::vector<std::optional<std::string>>>,
        // ndk::AParcel_readVector), PARCEL_READ(std::vector<SomeParcelable>,
        // 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::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::optional<std::vector<int64_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::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::optional<std::vector<double>>, ndk::AParcel_readVector),
        // PARCEL_READ(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::optional<std::vector<char16_t>>, ndk::AParcel_readVector),
        // PARCEL_READ(std::vector<int32_t>, ndk::AParcel_resizeVector),
        // PARCEL_READ(std::optional<std::vector<int32_t>>, ndk::AParcel_resizeVector),

        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::vector<SomeParcelable>, 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::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::optional<std::vector<int64_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::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::optional<std::vector<double>>, ndk::AParcel_readVector),
        PARCEL_READ(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::optional<std::vector<char16_t>>, ndk::AParcel_readVector),
        PARCEL_READ(std::vector<int32_t>, ndk::AParcel_resizeVector),
        PARCEL_READ(std::optional<std::vector<int32_t>>, ndk::AParcel_resizeVector),
};
// clang-format on