OSDN Git Service

libgui: Prevent segfaulting in abandoned ConsumerBase
authorPablo Ceballos <pceballos@google.com>
Wed, 4 May 2016 20:59:35 +0000 (13:59 -0700)
committerPablo Ceballos <pceballos@google.com>
Wed, 4 May 2016 20:59:35 +0000 (13:59 -0700)
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
libs/gui/ConsumerBase.cpp
libs/gui/CpuConsumer.cpp
libs/gui/GLConsumer.cpp

index 6f4c89d..3491043 100644 (file)
@@ -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);
 }
index 2187e5e..a6a9712 100644 (file)
@@ -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> 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.
index 7ed3d0f..8393160 100644 (file)
@@ -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);
 }
index ac8bc6e..cebcc4e 100644 (file)
@@ -208,6 +208,10 @@ GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& 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);
 }