hwc: Fix to avoid heap corruption
- Check for MAX_NUM_APP_LAYERS before updating yuv indices array.
- Fall back to GPU composition when number of app layers exceeds
MAX_NUM_APP_LAYERS to avoid heap corruption.
Change-Id: Ieb91b705a0a5f50ce2f8829d1f1ee048d44b7d2e
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 1f724de..2adb2ab 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -153,7 +153,7 @@
return false;
}
- if (ctx->listStats[dpy].numAppLayers > MAX_NUM_LAYERS) {
+ if (ctx->listStats[dpy].numAppLayers > MAX_NUM_APP_LAYERS) {
// Reached max layers supported by HWC.
return false;
}
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 0911248..ff48d79 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -366,6 +366,10 @@
ctx->isPaddingRound = false;
ALOGD_IF(isDebug(), "%s: padding round",__FUNCTION__);
ret = false;
+ } else if(numAppLayers > MAX_NUM_APP_LAYERS) {
+ ALOGD_IF(isDebug(), "%s: Number of App layers exceeded the limit ",
+ __FUNCTION__);
+ ret = false;
}
return ret;
}
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index a0255b7..e2800d2 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -78,7 +78,7 @@
struct FrameInfo {
/* maps layer list to mdp list */
int layerCount;
- int layerToMDP[MAX_NUM_LAYERS];
+ int layerToMDP[MAX_NUM_APP_LAYERS];
/* maps mdp list to layer list */
int mdpCount;
@@ -86,7 +86,7 @@
/* layer composing on FB? */
int fbCount;
- bool isFBComposed[MAX_NUM_LAYERS];
+ bool isFBComposed[MAX_NUM_APP_LAYERS];
bool needsRedraw;
int fbZ;
@@ -104,7 +104,7 @@
int mdpCount;
int cacheCount;
int fbZ;
- buffer_handle_t hnd[MAX_NUM_LAYERS];
+ buffer_handle_t hnd[MAX_NUM_APP_LAYERS];
/* c'tor */
LayerCache();
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index b0ea0fc..d07db5d 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -368,12 +368,21 @@
ctx->listStats[dpy].extOnlyLayerIndex = -1;
ctx->listStats[dpy].isDisplayAnimating = false;
- for (size_t i = 0; i < list->numHwLayers; i++) {
+ //reset yuv indices
+ memset(ctx->listStats[dpy].yuvIndices, -1, MAX_NUM_APP_LAYERS);
+
+ for (size_t i = 0; i < (list->numHwLayers - 1); i++) {
hwc_layer_1_t const* layer = &list->hwLayers[i];
private_handle_t *hnd = (private_handle_t *)layer->handle;
- //reset stored yuv index
- ctx->listStats[dpy].yuvIndices[i] = -1;
+#ifdef QCOM_BSP
+ if (layer->flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
+ ctx->listStats[dpy].isDisplayAnimating = true;
+ }
+#endif
+ // continue if i reaches MAX_NUM_APP_LAYERS
+ if(i >= MAX_NUM_APP_LAYERS)
+ continue;
if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
continue;
@@ -405,11 +414,6 @@
if(UNLIKELY(isExtOnly(hnd))){
ctx->listStats[dpy].extOnlyLayerIndex = i;
}
-#ifdef QCOM_BSP
- if (layer->flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
- ctx->listStats[dpy].isDisplayAnimating = true;
- }
-#endif
}
if(ctx->listStats[dpy].yuvCount > 0) {
if (property_get("hw.cabl.yuv", property, NULL) > 0) {
@@ -596,7 +600,7 @@
int fd) {
int ret = 0;
struct mdp_buf_sync data;
- int acquireFd[MAX_NUM_LAYERS];
+ int acquireFd[MAX_NUM_APP_LAYERS];
int count = 0;
int releaseFd = -1;
int fbFd = -1;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 729a649..54a118c 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -33,7 +33,7 @@
#define ALIGN_TO(x, align) (((x) + ((align)-1)) & ~((align)-1))
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-#define MAX_NUM_LAYERS 32 //includes fb layer
+#define MAX_NUM_APP_LAYERS 32
// For support of virtual displays
#define HWC_DISPLAY_VIRTUAL (HWC_DISPLAY_EXTERNAL+1)
@@ -90,7 +90,7 @@
int fbLayerIndex; //Always last for now. = numAppLayers
//Video specific
int yuvCount;
- int yuvIndices[MAX_NUM_LAYERS];
+ int yuvIndices[MAX_NUM_APP_LAYERS];
int extOnlyLayerIndex;
bool needsAlphaScale;
bool preMultipliedAlpha;