Allocate backing bo in CreatePixmap2 where it can safely fail
Previously we waited until ModifyPixmapHeader to
allocate the backing dumb_bo for the pixmap. If
this allocation failed, X would ignore it and end
up dereferencing a NULL pointer later on.
As CreatePixmap2 gives us all the info needed to
calculate the backing dumb_bo size, we can just
allocate it here. If this entrypoint fails, X will
report the error back to the client and carry on
normally.
Change-Id: I3de512c3e8981af4b4455796c8180101b6996512
diff --git a/src/omap_dri2.c b/src/omap_dri2.c
index cc7e418..237efac 100644
--- a/src/omap_dri2.c
+++ b/src/omap_dri2.c
@@ -184,12 +184,20 @@
pPixmap = createpix(pDraw);
}
+ if (!pPixmap)
+ {
+ assert(attachment != DRI2BufferFrontLeft);
+ ERROR_MSG("Failed to create back buffer for window");
+ free(buf);
+ return NULL;
+ }
+
bo = OMAPPixmapBo(pPixmap);
if (!bo)
{
ERROR_MSG("Attempting to DRI2 wrap a pixmap with no DRM buffer object backing");
- /* TODO: MIDEGL-1462: Returning NULL here ends up in a segfault all the way in pixman which has no backtrace.
- * We get a more friendly segfault if we just let it be dereferenced in a few lines */
+ free(buf);
+ return NULL;
}
DRIBUF(buf)->attachment = attachment;
diff --git a/src/omap_exa.c b/src/omap_exa.c
index b1f40c0..69b6e1a 100644
--- a/src/omap_exa.c
+++ b/src/omap_exa.c
@@ -77,13 +77,36 @@
}
_X_EXPORT void *
-OMAPCreatePixmap (ScreenPtr pScreen, int width, int height,
+OMAPCreatePixmap2 (ScreenPtr pScreen, int width, int height,
int depth, int usage_hint, int bitsPerPixel,
int *new_fb_pitch)
{
OMAPPixmapPrivPtr priv = calloc(sizeof(OMAPPixmapPrivRec), 1);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ OMAPPtr pOMAP = OMAPPTR(pScrn);
- /* actual allocation of buffer is in OMAPModifyPixmapHeader */
+ enum omap_buf_type buf_type = OMAP_BO_NON_SCANOUT;
+ if (usage_hint & OMAP_CREATE_PIXMAP_SCANOUT)
+ {
+ buf_type = OMAP_BO_SCANOUT;
+ }
+
+ if (width > 0 && height > 0 && depth > 0 && bitsPerPixel > 0)
+ {
+ priv->bo = omap_bo_new_with_dim(pOMAP->dev,
+ width,
+ height,
+ depth,
+ bitsPerPixel, buf_type);
+ if (!priv->bo)
+ {
+ ERROR_MSG("failed to allocate %dx%d bo, buf_type = %d",
+ width, height, buf_type);
+ free(priv);
+ return NULL;
+ }
+ *new_fb_pitch = omap_bo_pitch(priv->bo);
+ }
/* The usage_hint field of the Pixmap passed to ModifyPixmapHeader is not
* set to the usage_hint parameter passed to CreatePixmap.
diff --git a/src/omap_exa.h b/src/omap_exa.h
index 0ccc1d1..e8952f2 100644
--- a/src/omap_exa.h
+++ b/src/omap_exa.h
@@ -134,7 +134,7 @@
#define OMAP_CREATE_PIXMAP_TILED 0x40000000
-void * OMAPCreatePixmap (ScreenPtr pScreen, int width, int height,
+void * OMAPCreatePixmap2 (ScreenPtr pScreen, int width, int height,
int depth, int usage_hint, int bitsPerPixel,
int *new_fb_pitch);
void OMAPDestroyPixmap(ScreenPtr pScreen, void *driverPriv);
diff --git a/src/omap_exa_null.c b/src/omap_exa_null.c
index 259be33..b821d30 100644
--- a/src/omap_exa_null.c
+++ b/src/omap_exa_null.c
@@ -120,7 +120,7 @@
/* Required EXA functions: */
exa->WaitMarker = OMAPWaitMarker;
- exa->CreatePixmap2 = OMAPCreatePixmap;
+ exa->CreatePixmap2 = OMAPCreatePixmap2;
exa->DestroyPixmap = OMAPDestroyPixmap;
exa->ModifyPixmapHeader = OMAPModifyPixmapHeader;