Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 23c21baf authored by Dave Sparks's avatar Dave Sparks
Browse files

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.
parent c47c0789
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -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.

    // 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;