diff options
author | Jamie Gennis <jgennis@google.com> | 2011-06-20 12:04:09 -0700 |
---|---|---|
committer | Jamie Gennis <jgennis@google.com> | 2011-06-20 14:16:49 -0700 |
commit | aff74054189a4276a250eac91ac301ab2df37ae3 (patch) | |
tree | 9ff93cb4a6667ffd4692e07cab3f5b4125729a2d /libs | |
parent | f71e5469441286c6f466043e64a7f6492557cbd9 (diff) | |
download | frameworks_base-aff74054189a4276a250eac91ac301ab2df37ae3.zip frameworks_base-aff74054189a4276a250eac91ac301ab2df37ae3.tar.gz frameworks_base-aff74054189a4276a250eac91ac301ab2df37ae3.tar.bz2 |
SurfaceTexture: fix a NULL ptr dereference.
This change adds a NULL check when searching the slot list in
SurfaceTextureClient for the slot corresponding to a buffer being
queued or canceled.
Bug: 4645023
Change-Id: I806cbc1e34da118ea33a83c4f25ce8193ba1c3ad
Diffstat (limited to 'libs')
-rw-r--r-- | libs/gui/SurfaceTextureClient.cpp | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp index 22b0852..b9b2310 100644 --- a/libs/gui/SurfaceTextureClient.cpp +++ b/libs/gui/SurfaceTextureClient.cpp @@ -143,12 +143,40 @@ int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) { int SurfaceTextureClient::cancelBuffer(android_native_buffer_t* buffer) { LOGV("SurfaceTextureClient::cancelBuffer"); Mutex::Autolock lock(mMutex); + int i = getSlotFromBufferLocked(buffer); + if (i < 0) { + return i; + } + mSurfaceTexture->cancelBuffer(i); + return OK; +} + +int SurfaceTextureClient::getSlotFromBufferLocked( + android_native_buffer_t* buffer) const { + bool dumpedState = false; for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { - if (mSlots[i]->handle == buffer->handle) { - mSurfaceTexture->cancelBuffer(i); - return OK; + // XXX: Dump the slots whenever we hit a NULL entry while searching for + // a buffer. + if (mSlots[i] == NULL) { + if (!dumpedState) { + LOGD("getSlotFromBufferLocked: encountered NULL buffer in slot %d " + "looking for buffer %p", i, buffer->handle); + for (int j = 0; j < NUM_BUFFER_SLOTS; j++) { + if (mSlots[j] == NULL) { + LOGD("getSlotFromBufferLocked: %02d: NULL", j); + } else { + LOGD("getSlotFromBufferLocked: %02d: %p", j, mSlots[j]->handle); + } + } + dumpedState = true; + } + } + + if (mSlots[i] != NULL && mSlots[i]->handle == buffer->handle) { + return i; } } + LOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle); return BAD_VALUE; } @@ -169,13 +197,12 @@ int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) { } else { timestamp = mTimestamp; } - for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { - if (mSlots[i]->handle == buffer->handle) { - return mSurfaceTexture->queueBuffer(i, timestamp); - } + int i = getSlotFromBufferLocked(buffer); + if (i < 0) { + return i; } - LOGE("queueBuffer: unknown buffer queued"); - return BAD_VALUE; + mSurfaceTexture->queueBuffer(i, timestamp); + return OK; } int SurfaceTextureClient::query(int what, int* value) const { |