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

Commit b2290930 authored by Aaron Vaage's avatar Aaron Vaage
Browse files

Fixing MediaCodec::getBufferAndFormat returns OK on invalid state

Defined safe outcomes for when given an index that is out of
bounds or when the index points to a buffer that is not owned
by the client.

While at it, added guards against NULL parameters.

Bug: 23112275
Change-Id: I7919e75a0bb91dc2c97736623624ecbbdbe6ea4b
parent e6eeff25
Loading
Loading
Loading
Loading
+33 −12
Original line number Diff line number Diff line
@@ -844,33 +844,54 @@ status_t MediaCodec::getBufferAndFormat(
        size_t portIndex, size_t index,
        sp<ABuffer> *buffer, sp<AMessage> *format) {
    // use mutex instead of a context switch

    if (mReleasedByResourceManager) {
        ALOGE("getBufferAndFormat - resource already released");
        return DEAD_OBJECT;
    }

    if (buffer == NULL) {
        ALOGE("getBufferAndFormat - null ABuffer");
        return INVALID_OPERATION;
    }

    if (format == NULL) {
        ALOGE("getBufferAndFormat - null AMessage");
        return INVALID_OPERATION;
    }

    buffer->clear();
    format->clear();

    if (!isExecuting()) {
        ALOGE("getBufferAndFormat - not executing");
        return INVALID_OPERATION;
    }

    // we do not want mPortBuffers to change during this section
    // we also don't want mOwnedByClient to change during this
    Mutex::Autolock al(mBufferLock);

    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
    if (index < buffers->size()) {
    if (index >= buffers->size()) {
        ALOGE("getBufferAndFormat - trying to get buffer with "
              "bad index (index=%u buffer_size=%u)", index, buffers->size());
        return INVALID_OPERATION;
    }

    const BufferInfo &info = buffers->itemAt(index);
        if (info.mOwnedByClient) {
            // by the time buffers array is initialized, crypto is set
            if (portIndex == kPortIndexInput && mCrypto != NULL) {
                *buffer = info.mEncryptedData;
            } else {
                *buffer = info.mData;
    if (!info.mOwnedByClient) {
        ALOGE("getBufferAndFormat - invalid operation "
              "(index %u is not owned by client)", index);
        return INVALID_OPERATION;
    }

    // by the time buffers array is initialized, crypto is set
    *buffer = (portIndex == kPortIndexInput && mCrypto != NULL) ?
                  info.mEncryptedData :
                  info.mData;

    *format = info.mFormat;
        }
    }

    return OK;
}