From c8093c11286e3c65fb6de686db17b87b0efb1e56 Mon Sep 17 00:00:00 2001 From: Dave Sparks Date: Fri, 6 Nov 2009 11:47:13 -0800 Subject: 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. --- camera/libcameraservice/CameraService.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'camera/libcameraservice/CameraService.cpp') 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& // 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 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 frame = new MemoryBase(mPreviewBuffer, 0, size); + sp frame = new MemoryBase(previewBuffer, 0, size); if (frame == 0) { LOGE("failed to allocate space for frame callback"); return; -- cgit v1.1