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 /camera | |
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.
Diffstat (limited to 'camera')
-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; |