From bd80b38f2945ac918f66fb336c149b28b9dd030e Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 7 Jul 2009 17:53:43 -0700 Subject: more fixes for [1965730]. We now free (unmap) both ashmem and pmem regions. --- modules/gralloc/gralloc.cpp | 40 +++++++++++++++++++--------------------- modules/gralloc/gralloc_priv.h | 2 ++ modules/gralloc/mapper.cpp | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 22 deletions(-) (limited to 'modules/gralloc') diff --git a/modules/gralloc/gralloc.cpp b/modules/gralloc/gralloc.cpp index a01a95c..8c496dc 100644 --- a/modules/gralloc/gralloc.cpp +++ b/modules/gralloc/gralloc.cpp @@ -389,38 +389,36 @@ static int gralloc_free(alloc_device_t* dev, return -EINVAL; private_handle_t const* hnd = reinterpret_cast(handle); - if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) - { + if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { // free this buffer private_module_t* m = reinterpret_cast( dev->common.module); const size_t bufferSize = m->finfo.line_length * m->info.yres; int index = (hnd->base - m->framebuffer->base) / bufferSize; m->bufferMask &= ~(1<flags & private_handle_t::PRIV_FLAGS_USES_PMEM) - { - if (hnd->fd >= 0) { - struct pmem_region sub = { hnd->offset, hnd->size }; - int err = ioctl(hnd->fd, PMEM_UNMAP, &sub); - LOGE_IF(err<0, "PMEM_UNMAP failed (%s), " - "fd=%d, sub.offset=%lu, sub.size=%lu", - strerror(errno), hnd->fd, hnd->offset, hnd->size); - if (err == 0) { - // we can't deallocate the memory in case of UNMAP failure - // because it would give that process access to someone else's - // surfaces, which would be a security breach. - sAllocator.deallocate(hnd->offset); + if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM) { + if (hnd->fd >= 0) { + struct pmem_region sub = { hnd->offset, hnd->size }; + int err = ioctl(hnd->fd, PMEM_UNMAP, &sub); + LOGE_IF(err<0, "PMEM_UNMAP failed (%s), " + "fd=%d, sub.offset=%lu, sub.size=%lu", + strerror(errno), hnd->fd, hnd->offset, hnd->size); + if (err == 0) { + // we can't deallocate the memory in case of UNMAP failure + // because it would give that process access to someone else's + // surfaces, which would be a security breach. + sAllocator.deallocate(hnd->offset); + } } } - } #endif // HAVE_ANDROID_OS + gralloc_module_t* module = reinterpret_cast( + dev->common.module); + terminateBuffer(module, const_cast(hnd)); + } - gralloc_module_t* m = reinterpret_cast( - dev->common.module); - gralloc_unregister_buffer(m, handle); - close(hnd->fd); delete hnd; return 0; diff --git a/modules/gralloc/gralloc_priv.h b/modules/gralloc/gralloc_priv.h index aa757b1..bfd3635 100644 --- a/modules/gralloc/gralloc_priv.h +++ b/modules/gralloc/gralloc_priv.h @@ -37,12 +37,14 @@ /*****************************************************************************/ struct private_module_t; +struct private_handle_t; inline size_t roundUpToPageSize(size_t x) { return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); } int mapFrameBufferLocked(struct private_module_t* module); +int terminateBuffer(gralloc_module_t const* module, private_handle_t* hnd); /*****************************************************************************/ diff --git a/modules/gralloc/mapper.cpp b/modules/gralloc/mapper.cpp index 75a9bb6..323f5d8 100644 --- a/modules/gralloc/mapper.cpp +++ b/modules/gralloc/mapper.cpp @@ -75,7 +75,14 @@ static int gralloc_unmap(gralloc_module_t const* module, { private_handle_t* hnd = (private_handle_t*)handle; if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { - if (munmap((void*)hnd->base, hnd->size) < 0) { + void* base = (void*)hnd->base; + size_t size = hnd->size; +#if PMEM_HACK + base = (void*)(intptr_t(base) - hnd->offset); + size += hnd->offset; +#endif + //LOGD("unmapping from %p, size=%d", base, size); + if (munmap(base, size) < 0) { LOGE("Could not unmap %s", strerror(errno)); } } @@ -144,6 +151,33 @@ int gralloc_unregister_buffer(gralloc_module_t const* module, return 0; } +int terminateBuffer(gralloc_module_t const* module, + private_handle_t* hnd) +{ + /* + * If the buffer has been mapped during a lock operation, it's time + * to un-map it. It's an error to be here with a locked buffer. + */ + + LOGE_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK, + "handle %p still locked (state=%08x)", + hnd, hnd->lockState); + + if (hnd->lockState & private_handle_t::LOCK_STATE_MAPPED) { + // this buffer was mapped, unmap it now + if ((hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM) && + (hnd->pid == getpid())) { + // ... unless it's a "master" pmem buffer, that is a buffer + // mapped in the process it's been allocated. + // (see gralloc_alloc_buffer()) + } else { + gralloc_unmap(module, hnd); + } + } + + return 0; +} + int gralloc_lock(gralloc_module_t const* module, buffer_handle_t handle, int usage, int l, int t, int w, int h, -- cgit v1.1