draw: check for out-of-memory conditions in the AA line module.
authorMatthew McClure <mcclurem@vmware.com>
Fri, 21 Jun 2013 19:44:44 +0000 (12:44 -0700)
committerBrian Paul <brianp@vmware.com>
Mon, 24 Jun 2013 14:36:47 +0000 (08:36 -0600)
To prevent segfaults in the AA line module, the code will check for a
valid pointer to the aaline_stage in the draw context.

Fixes segfault from backtrace:

* aaline_stage_from_pipe
  aaline_delete_fs_state

Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/auxiliary/draw/draw_pipe_aaline.c

index b6c328b2db91dd9c8cda15042251ddc5b01029af..aa884596b357b6592ff033b76d2eed23309b8af3 100644 (file)
@@ -831,7 +831,12 @@ static struct aaline_stage *
 aaline_stage_from_pipe(struct pipe_context *pipe)
 {
    struct draw_context *draw = (struct draw_context *) pipe->draw;
-   return aaline_stage(draw->pipeline.aaline);
+
+   if (draw) {
+      return aaline_stage(draw->pipeline.aaline);
+   } else {
+      return NULL;
+   }
 }
 
 
@@ -844,7 +849,12 @@ aaline_create_fs_state(struct pipe_context *pipe,
                        const struct pipe_shader_state *fs)
 {
    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
-   struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader);
+   struct aaline_fragment_shader *aafs = NULL;
+
+   if (aaline == NULL)
+      return NULL;
+
+   aafs = CALLOC_STRUCT(aaline_fragment_shader);
 
    if (aafs == NULL)
       return NULL;
@@ -864,6 +874,10 @@ aaline_bind_fs_state(struct pipe_context *pipe, void *fs)
    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
    struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
 
+   if (aaline == NULL) {
+      return;
+   }
+
    /* save current */
    aaline->fs = aafs;
    /* pass-through */
@@ -877,14 +891,19 @@ aaline_delete_fs_state(struct pipe_context *pipe, void *fs)
    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
    struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
 
-   /* pass-through */
-   aaline->driver_delete_fs_state(pipe, aafs->driver_fs);
+   if (aafs == NULL) {
+      return;
+   }
 
-   if (aafs->aaline_fs)
-      aaline->driver_delete_fs_state(pipe, aafs->aaline_fs);
+   if (aaline != NULL) {
+      /* pass-through */
+      aaline->driver_delete_fs_state(pipe, aafs->driver_fs);
 
-   FREE((void*)aafs->state.tokens);
+      if (aafs->aaline_fs)
+         aaline->driver_delete_fs_state(pipe, aafs->aaline_fs);
+   }
 
+   FREE((void*)aafs->state.tokens);
    FREE(aafs);
 }
 
@@ -895,6 +914,10 @@ aaline_bind_sampler_states(struct pipe_context *pipe,
 {
    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
 
+   if (aaline == NULL) {
+      return;
+   }
+
    /* save current */
    memcpy(aaline->state.sampler, sampler, num * sizeof(void *));
    aaline->num_samplers = num;
@@ -912,6 +935,10 @@ aaline_set_sampler_views(struct pipe_context *pipe,
    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
    uint i;
 
+   if (aaline == NULL) {
+      return;
+   }
+
    /* save current */
    for (i = 0; i < num; i++) {
       pipe_sampler_view_reference(&aaline->state.sampler_views[i], views[i]);