From 65d9f6d63ab3bad1d835df14c662028a748eb3c5 Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Wed, 4 May 2016 13:59:35 -0700 Subject: [PATCH] libgui: Prevent segfaulting in abandoned ConsumerBase mConsumer will be null if the ConsumerBase has been abandoned. Prevent it from being dereferenced in those cases. Bug 27718219 Change-Id: I9a3ecadb0655ec61cd2fd15ee98b3e1bef078cff --- libs/gui/BufferItemConsumer.cpp | 4 ++++ libs/gui/ConsumerBase.cpp | 30 ++++++++++++++++++++++++++++++ libs/gui/CpuConsumer.cpp | 4 ++++ libs/gui/GLConsumer.cpp | 28 ++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+) diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp index 6f4c89dd8d..3491043811 100644 --- a/libs/gui/BufferItemConsumer.cpp +++ b/libs/gui/BufferItemConsumer.cpp @@ -49,6 +49,10 @@ BufferItemConsumer::~BufferItemConsumer() {} void BufferItemConsumer::setName(const String8& name) { Mutex::Autolock _l(mMutex); + if (mAbandoned) { + BI_LOGE("setName: BufferItemConsumer is abandoned!"); + return; + } mName = name; mConsumer->setConsumerName(name); } diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp index 2187e5e8eb..a6a971282e 100644 --- a/libs/gui/ConsumerBase.cpp +++ b/libs/gui/ConsumerBase.cpp @@ -163,6 +163,10 @@ void ConsumerBase::abandon() { void ConsumerBase::abandonLocked() { CB_LOGV("abandonLocked"); + if (mAbandoned) { + CB_LOGE("abandonLocked: ConsumerBase is abandoned!"); + return; + } for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { freeBufferLocked(i); } @@ -187,6 +191,11 @@ status_t ConsumerBase::detachBuffer(int slot) { CB_LOGV("detachBuffer"); Mutex::Autolock lock(mMutex); + if (mAbandoned) { + CB_LOGE("detachBuffer: ConsumerBase is abandoned!"); + return NO_INIT; + } + status_t result = mConsumer->detachBuffer(slot); if (result != NO_ERROR) { CB_LOGE("Failed to detach buffer: %d", result); @@ -200,17 +209,29 @@ status_t ConsumerBase::detachBuffer(int slot) { status_t ConsumerBase::setDefaultBufferSize(uint32_t width, uint32_t height) { Mutex::Autolock _l(mMutex); + if (mAbandoned) { + CB_LOGE("setDefaultBufferSize: ConsumerBase is abandoned!"); + return NO_INIT; + } return mConsumer->setDefaultBufferSize(width, height); } status_t ConsumerBase::setDefaultBufferFormat(PixelFormat defaultFormat) { Mutex::Autolock _l(mMutex); + if (mAbandoned) { + CB_LOGE("setDefaultBufferFormat: ConsumerBase is abandoned!"); + return NO_INIT; + } return mConsumer->setDefaultBufferFormat(defaultFormat); } status_t ConsumerBase::setDefaultBufferDataSpace( android_dataspace defaultDataSpace) { Mutex::Autolock _l(mMutex); + if (mAbandoned) { + CB_LOGE("setDefaultBufferDataSpace: ConsumerBase is abandoned!"); + return NO_INIT; + } return mConsumer->setDefaultBufferDataSpace(defaultDataSpace); } @@ -233,6 +254,11 @@ void ConsumerBase::dumpLocked(String8& result, const char* prefix) const { status_t ConsumerBase::acquireBufferLocked(BufferItem *item, nsecs_t presentWhen, uint64_t maxFrameNumber) { + if (mAbandoned) { + CB_LOGE("acquireBufferLocked: ConsumerBase is abandoned!"); + return NO_INIT; + } + status_t err = mConsumer->acquireBuffer(item, presentWhen, maxFrameNumber); if (err != NO_ERROR) { return err; @@ -289,6 +315,10 @@ status_t ConsumerBase::addReleaseFenceLocked(int slot, status_t ConsumerBase::releaseBufferLocked( int slot, const sp graphicBuffer, EGLDisplay display, EGLSyncKHR eglFence) { + if (mAbandoned) { + CB_LOGE("releaseBufferLocked: ConsumerBase is abandoned!"); + return NO_INIT; + } // If consumer no longer tracks this graphicBuffer (we received a new // buffer on the same slot), the buffer producer is definitely no longer // tracking it. diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp index 7ed3d0f893..839316021e 100644 --- a/libs/gui/CpuConsumer.cpp +++ b/libs/gui/CpuConsumer.cpp @@ -52,6 +52,10 @@ CpuConsumer::~CpuConsumer() { void CpuConsumer::setName(const String8& name) { Mutex::Autolock _l(mMutex); + if (mAbandoned) { + CC_LOGE("setName: CpuConsumer is abandoned!"); + return; + } mName = name; mConsumer->setConsumerName(name); } diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp index ac8bc6eee7..cebcc4e4e7 100644 --- a/libs/gui/GLConsumer.cpp +++ b/libs/gui/GLConsumer.cpp @@ -208,6 +208,10 @@ GLConsumer::GLConsumer(const sp& bq, uint32_t texTarget, status_t GLConsumer::setDefaultBufferSize(uint32_t w, uint32_t h) { Mutex::Autolock lock(mMutex); + if (mAbandoned) { + GLC_LOGE("setDefaultBufferSize: GLConsumer is abandoned!"); + return NO_INIT; + } mDefaultWidth = w; mDefaultHeight = h; return mConsumer->setDefaultBufferSize(w, h); @@ -1073,34 +1077,58 @@ void GLConsumer::abandonLocked() { void GLConsumer::setName(const String8& name) { Mutex::Autolock _l(mMutex); + if (mAbandoned) { + GLC_LOGE("setName: GLConsumer is abandoned!"); + return; + } mName = name; mConsumer->setConsumerName(name); } status_t GLConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) { Mutex::Autolock lock(mMutex); + if (mAbandoned) { + GLC_LOGE("setDefaultBufferFormat: GLConsumer is abandoned!"); + return NO_INIT; + } return mConsumer->setDefaultBufferFormat(defaultFormat); } status_t GLConsumer::setDefaultBufferDataSpace( android_dataspace defaultDataSpace) { Mutex::Autolock lock(mMutex); + if (mAbandoned) { + GLC_LOGE("setDefaultBufferDataSpace: GLConsumer is abandoned!"); + return NO_INIT; + } return mConsumer->setDefaultBufferDataSpace(defaultDataSpace); } status_t GLConsumer::setConsumerUsageBits(uint32_t usage) { Mutex::Autolock lock(mMutex); + if (mAbandoned) { + GLC_LOGE("setConsumerUsageBits: GLConsumer is abandoned!"); + return NO_INIT; + } usage |= DEFAULT_USAGE_FLAGS; return mConsumer->setConsumerUsageBits(usage); } status_t GLConsumer::setTransformHint(uint32_t hint) { Mutex::Autolock lock(mMutex); + if (mAbandoned) { + GLC_LOGE("setTransformHint: GLConsumer is abandoned!"); + return NO_INIT; + } return mConsumer->setTransformHint(hint); } status_t GLConsumer::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { Mutex::Autolock lock(mMutex); + if (mAbandoned) { + GLC_LOGE("setMaxAcquiredBufferCount: GLConsumer is abandoned!"); + return NO_INIT; + } return mConsumer->setMaxAcquiredBufferCount(maxAcquiredBuffers); } -- 2.11.0