libhwcomposer: Unregister layer handles that fail validation.

Layer buffer handles that fail gralloc validation must be removed
from hwcomposer's register of previous bypass and overlay handles.

(cherry picked from commit 18c7f1951018b6632bd6e1a4957194c01423b6ee)

Change-Id: Idaaf3557b05adb5b3e938e9cd46dac5b104b729e
CRs-Fixed: 347157
This commit is contained in:
Mathew Karimpanal 2012-04-16 20:02:20 -07:00 committed by Andrew Sutherland
parent 4e0b4170a1
commit 49e5cace38
2 changed files with 64 additions and 37 deletions

View File

@ -380,7 +380,24 @@ struct private_handle_t {
h->numInts != sNumInts || h->numFds != sNumFds ||
hnd->magic != sMagic)
{
LOGE("invalid gralloc handle (at %p)", h);
LOGE("Invalid gralloc handle (at %p): "
"ver(%d/%d) ints(%d/%d) fds(%d/%d) magic(%c%c%c%c/%c%c%c%c)",
h,
h ? h->version : -1, sizeof(native_handle),
h ? h->numInts : -1, sNumInts,
h ? h->numFds : -1, sNumFds,
hnd ? (((hnd->magic >> 24) & 0xFF)?
((hnd->magic >> 24) & 0xFF) : '-') : '?',
hnd ? (((hnd->magic >> 16) & 0xFF)?
((hnd->magic >> 16) & 0xFF) : '-') : '?',
hnd ? (((hnd->magic >> 8) & 0xFF)?
((hnd->magic >> 8) & 0xFF) : '-') : '?',
hnd ? (((hnd->magic >> 0) & 0xFF)?
((hnd->magic >> 0) & 0xFF) : '-') : '?',
(sMagic >> 24) & 0xFF,
(sMagic >> 16) & 0xFF,
(sMagic >> 8) & 0xFF,
(sMagic >> 0) & 0xFF);
return -EINVAL;
}
return 0;

82
libhwcomposer/hwcomposer.cpp Executable file → Normal file
View File

@ -179,25 +179,29 @@ int getLayerbypassIndex(hwc_layer_t* layer)
}
void unlockPreviousBypassBuffers(hwc_context_t* ctx) {
// Unlock the previous bypass buffers. We can blindly unlock the buffers here,
// because buffers will be in this list only if the lock was successfully acquired.
for(int i = 0; i < MAX_BYPASS_LAYERS && ctx->previousBypassHandle[i]; i++) {
private_handle_t *hnd = (private_handle_t*) ctx->previousBypassHandle[i];
// Validate the handle to make sure it hasn't been deallocated.
if (private_handle_t::validate(ctx->previousBypassHandle[i])) {
// Unlock the previous bypass buffers. We can blindly unlock the buffers
// here, because buffers will be in this list only if the lock was
// successfully acquired.
for(int i = 0; i < MAX_BYPASS_LAYERS; i++) {
private_handle_t *hnd = (private_handle_t*) ctx->previousBypassHandle[i];
if (!hnd)
continue;
}
// Check if the handle was locked previously
if (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags) {
if (GENLOCK_FAILURE == genlock_unlock_buffer(ctx->previousBypassHandle[i])) {
LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
} else {
ctx->previousBypassHandle[i] = NULL;
// Reset the lock flag
hnd->flags &= ~private_handle_t::PRIV_FLAGS_HWC_LOCK;
}
}
// Validate the handle to make sure it hasn't been deallocated.
if (private_handle_t::validate(hnd)) {
LOGE("%s: Unregistering invalid gralloc handle %p.", __FUNCTION__, hnd);
ctx->previousBypassHandle[i] = NULL;
continue;
}
// Check if the handle was locked previously
if (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags) {
if (GENLOCK_FAILURE == genlock_unlock_buffer(hnd)) {
LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
} else {
ctx->previousBypassHandle[i] = NULL;
// Reset the lock flag
hnd->flags &= ~private_handle_t::PRIV_FLAGS_HWC_LOCK;
}
}
}
}
@ -525,17 +529,20 @@ void closeExtraPipes(hwc_context_t* ctx) {
//Unused pipes must be of higher z-order
for (int i = pipes_used ; i < MAX_BYPASS_LAYERS; i++) {
if (ctx->previousBypassHandle[i]) {
private_handle_t *hnd = (private_handle_t*) ctx->previousBypassHandle[i];
if (!private_handle_t::validate(ctx->previousBypassHandle[i])) {
if (GENLOCK_FAILURE == genlock_unlock_buffer(ctx->previousBypassHandle[i])) {
private_handle_t *hnd = (private_handle_t*) ctx->previousBypassHandle[i];
if (hnd) {
if (!private_handle_t::validate(hnd)) {
if (GENLOCK_FAILURE == genlock_unlock_buffer(hnd)) {
LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
} else {
ctx->previousBypassHandle[i] = NULL;
ctx->bypassBufferLockState[i] = BYPASS_BUFFER_UNLOCKED;
hnd->flags &= ~private_handle_t::PRIV_FLAGS_HWC_LOCK;
}
} else {
LOGE("%s: Unregistering invalid gralloc handle %p.",
__FUNCTION__, hnd);
ctx->previousBypassHandle[i] = NULL;
}
}
ctx->mOvUI[i]->closeChannel();
@ -713,15 +720,18 @@ static int prepareOverlay(hwc_context_t *ctx, hwc_layer_t *layer, const int flag
void unlockPreviousOverlayBuffer(hwc_context_t* ctx)
{
private_handle_t *hnd = (private_handle_t*)ctx->previousOverlayHandle;
if (isBufferLocked(hnd) && !private_handle_t::validate(hnd)) {
if (GENLOCK_NO_ERROR == genlock_unlock_buffer(hnd)) {
//If previous is same as current, keep locked.
if(hnd != ctx->currentOverlayHandle) {
hnd->flags &= ~private_handle_t::PRIV_FLAGS_HWC_LOCK;
private_handle_t *hnd = (private_handle_t*) ctx->previousOverlayHandle;
if (hnd) {
// Validate the handle before attempting to use it.
if (!private_handle_t::validate(hnd) && isBufferLocked(hnd)) {
if (GENLOCK_NO_ERROR == genlock_unlock_buffer(hnd)) {
//If previous is same as current, keep locked.
if(hnd != ctx->currentOverlayHandle) {
hnd->flags &= ~private_handle_t::PRIV_FLAGS_HWC_LOCK;
}
} else {
LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
}
} else {
LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__);
}
}
ctx->previousOverlayHandle = ctx->currentOverlayHandle;
@ -1207,19 +1217,19 @@ static int drawLayerUsingCopybit(hwc_composer_device_t *dev, hwc_layer_t *layer,
{
hwc_context_t* ctx = (hwc_context_t*)(dev);
if(!ctx) {
LOGE("drawLayerUsingCopybit null context ");
LOGE("%s: null context ", __FUNCTION__);
return -1;
}
private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(dev->common.module);
if(!hwcModule) {
LOGE("drawLayerUsingCopybit null module ");
LOGE("%s: null module ", __FUNCTION__);
return -1;
}
private_handle_t *hnd = (private_handle_t *)layer->handle;
if(!hnd) {
LOGE("drawLayerUsingCopybit invalid handle");
LOGE("%s: invalid handle", __FUNCTION__);
return -1;
}
@ -1233,13 +1243,13 @@ static int drawLayerUsingCopybit(hwc_composer_device_t *dev, hwc_layer_t *layer,
//render buffer
android_native_buffer_t *renderBuffer = (android_native_buffer_t *)eglGetRenderBufferANDROID(dpy, surface);
if (!renderBuffer) {
LOGE("eglGetRenderBufferANDROID returned NULL buffer");
LOGE("%s: eglGetRenderBufferANDROID returned NULL buffer", __FUNCTION__);
genlock_unlock_buffer(hnd);
return -1;
}
private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle;
if(!fbHandle) {
LOGE("Framebuffer handle is NULL");
LOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
genlock_unlock_buffer(hnd);
return -1;
}