summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Sparks <davidsparks@android.com>2009-11-06 11:47:13 -0800
committerDave Sparks <davidsparks@android.com>2009-11-06 11:47:13 -0800
commitc8093c11286e3c65fb6de686db17b87b0efb1e56 (patch)
tree68f24cfe8ea87bf8b1e228c9b4afab420c8986d5
parent8b1243e5e4930598e8e78ebd18e7b6cd6fb0445f (diff)
downloadframeworks_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.cpp21
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;