summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2011-10-25 17:39:57 +0200
committerMichel Dänzer <michel.daenzer@amd.com>2011-10-25 17:44:26 +0200
commit6e0e1a821accc6ca95f4134e49b66a6b168c1934 (patch)
treed955a0bdac6e122e30e8a3b558894771f87a525a
parent856583dbca9319c77fed40daa9956e81a0068f9e (diff)
Make radeon_dri2_create_buffer(s) more robust. (Bug #30047)
In particular, handle and propagate failure to allocate GPU accessible memory, instead of crashing. Fixes https://bugs.freedesktop.org/show_bug.cgi?id=30047 . Also take care not to leak resources in error paths. Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
-rw-r--r--src/radeon_dri2.c51
1 files changed, 33 insertions, 18 deletions
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 88117a55..8789d735 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -205,9 +205,17 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
exaMoveInPixmap(pixmap);
info->exa_force_create = FALSE;
driver_priv = exaGetPixmapDriverPrivate(pixmap);
- r = radeon_gem_get_kernel_name(driver_priv->bo, &buffers[i].name);
- if (r)
- return r;
+ if (!driver_priv ||
+ radeon_gem_get_kernel_name(driver_priv->bo, &buffers[i].name) != 0) {
+ int j;
+
+ for (j = 0; j < i; j++)
+ (*pScreen->DestroyPixmap)(privates[j].pixmap);
+ (*pScreen->DestroyPixmap)(pixmap);
+ free(privates);
+ free(buffers);
+ return NULL;
+ }
buffers[i].attachment = attachments[i];
buffers[i].pitch = pixmap->devKind;
@@ -232,7 +240,7 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
struct dri2_buffer_priv *privates;
PixmapPtr pixmap, depth_pixmap;
struct radeon_exa_pixmap_priv *driver_priv;
- int r, need_enlarge = 0;
+ int need_enlarge = 0;
int flags;
unsigned front_width;
uint32_t tiling = 0;
@@ -240,17 +248,7 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
pixmap = pScreen->GetScreenPixmap(pScreen);
front_width = pixmap->drawable.width;
- buffers = calloc(1, sizeof *buffers);
- if (buffers == NULL) {
- return NULL;
- }
- privates = calloc(1, sizeof(struct dri2_buffer_priv));
- if (privates == NULL) {
- free(buffers);
- return NULL;
- }
-
- depth_pixmap = NULL;
+ pixmap = depth_pixmap = NULL;
if (attachment == DRI2BufferFrontLeft) {
if (drawable->type == DRAWABLE_PIXMAP) {
@@ -351,6 +349,13 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
}
}
+ if (!pixmap)
+ return NULL;
+
+ buffers = calloc(1, sizeof *buffers);
+ if (buffers == NULL)
+ goto error;
+
if (attachment == DRI2BufferDepth) {
depth_pixmap = pixmap;
}
@@ -358,9 +363,13 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
exaMoveInPixmap(pixmap);
info->exa_force_create = FALSE;
driver_priv = exaGetPixmapDriverPrivate(pixmap);
- r = radeon_gem_get_kernel_name(driver_priv->bo, &buffers->name);
- if (r)
- return NULL;
+ if (!driver_priv ||
+ (radeon_gem_get_kernel_name(driver_priv->bo, &buffers->name) != 0))
+ goto error;
+
+ privates = calloc(1, sizeof(struct dri2_buffer_priv));
+ if (privates == NULL)
+ goto error;
buffers->attachment = attachment;
buffers->pitch = pixmap->devKind;
@@ -373,6 +382,12 @@ radeon_dri2_create_buffer(DrawablePtr drawable,
privates->refcnt = 1;
return buffers;
+
+error:
+ free(buffers);
+ if (pixmap)
+ (*pScreen->DestroyPixmap)(pixmap);
+ return NULL;
}
#endif