diff options
author | Dave Sparks <davidsparks@android.com> | 2009-11-06 11:47:13 -0800 |
---|---|---|
committer | Dave Sparks <davidsparks@android.com> | 2009-11-06 11:47:13 -0800 |
commit | c8093c11286e3c65fb6de686db17b87b0efb1e56 (patch) | |
tree | 68f24cfe8ea87bf8b1e228c9b4afab420c8986d5 | |
parent | 8b1243e5e4930598e8e78ebd18e7b6cd6fb0445f (diff) | |
download | frameworks_base-c8093c11286e3c65fb6de686db17b87b0efb1e56.zip frameworks_base-c8093c11286e3c65fb6de686db17b87b0efb1e56.tar.gz frameworks_base-c8093c11286e3c65fb6de686db17b87b0efb1e56.tar.bz2 |
Hold a lock while we access the preview heap.
copyFrameAndPostCopiedFrame was not holding a lock while it accessed
the preview heap. If the client process is torn down while the heap
is accessed, the memcpy could access memory that was deallocated.
This patch creates a local sp reference to the preview heap while
holding the lock, then releases the lock. This should prevent the
heap from being pulled out from underneath us.
-rw-r--r-- | camera/libcameraservice/CameraService.cpp | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp index 29531ca..e548524 100644 --- a/camera/libcameraservice/CameraService.cpp +++ b/camera/libcameraservice/CameraService.cpp @@ -1215,20 +1215,27 @@ void CameraService::Client::copyFrameAndPostCopiedFrame(const sp<ICameraClient>& // the callback. For efficiency, reuse the same MemoryHeapBase // provided it's big enough. Don't allocate the memory or // perform the copy if there's no callback. - if (mPreviewBuffer == 0) { - mPreviewBuffer = new MemoryHeapBase(size, 0, NULL); - } else if (size > mPreviewBuffer->virtualSize()) { - mPreviewBuffer.clear(); - mPreviewBuffer = new MemoryHeapBase(size, 0, NULL); + + // hold the lock while we grab a reference to the preview buffer + sp<MemoryHeapBase> previewBuffer; + { + Mutex::Autolock lock(mLock); + if (mPreviewBuffer == 0) { + mPreviewBuffer = new MemoryHeapBase(size, 0, NULL); + } else if (size > mPreviewBuffer->virtualSize()) { + mPreviewBuffer.clear(); + mPreviewBuffer = new MemoryHeapBase(size, 0, NULL); + } if (mPreviewBuffer == 0) { LOGE("failed to allocate space for preview buffer"); return; } + previewBuffer = mPreviewBuffer; } - memcpy(mPreviewBuffer->base(), + memcpy(previewBuffer->base(), (uint8_t *)heap->base() + offset, size); - sp<MemoryBase> frame = new MemoryBase(mPreviewBuffer, 0, size); + sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size); if (frame == 0) { LOGE("failed to allocate space for frame callback"); return; |