diff options
author | Michel Dänzer <michel.daenzer@amd.com> | 2011-10-25 17:39:57 +0200 |
---|---|---|
committer | Michel Dänzer <michel.daenzer@amd.com> | 2011-10-25 17:44:26 +0200 |
commit | 6e0e1a821accc6ca95f4134e49b66a6b168c1934 (patch) | |
tree | d955a0bdac6e122e30e8a3b558894771f87a525a | |
parent | 856583dbca9319c77fed40daa9956e81a0068f9e (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.c | 51 |
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 |