Mesa (main): glthread: Check out of bounds for MultiDrawElementsBaseVertex cmd

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jan 13 12:56:40 UTC 2022


Module: Mesa
Branch: main
Commit: fd2fbc558b8e9c6ffdfbd90473e5b77e20f771e7
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=fd2fbc558b8e9c6ffdfbd90473e5b77e20f771e7

Author: Vadym Shovkoplias <vadym.shovkoplias at globallogic.com>
Date:   Tue Jan 11 10:21:05 2022 +0200

glthread: Check out of bounds for MultiDrawElementsBaseVertex cmd

Make sure draw count is not high so the MultiDrawElementsBaseVertex cmd
can fit the queue buffer.

v2: add the same check for _mesa_marshal_MultiDrawArrays and add additional
    assert to _mesa_glthread_allocate_command (Pierre-Eric)

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5719
Signed-off-by: Vadym Shovkoplias <vadym.shovkoplias at globallogic.com>
Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14490>

---

 src/mesa/main/glthread_draw.c    | 28 +++++++++++++++++++++-------
 src/mesa/main/glthread_marshal.h |  2 ++
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/src/mesa/main/glthread_draw.c b/src/mesa/main/glthread_draw.c
index 7a0c72a6ff8..21fce5010ef 100644
--- a/src/mesa/main/glthread_draw.c
+++ b/src/mesa/main/glthread_draw.c
@@ -459,7 +459,7 @@ _mesa_unmarshal_MultiDrawArrays(struct gl_context *ctx,
    return cmd->cmd_base.cmd_size;
 }
 
-static ALWAYS_INLINE void
+static ALWAYS_INLINE bool
 multi_draw_arrays_async(struct gl_context *ctx, GLenum mode,
                         const GLint *first, const GLsizei *count,
                         GLsizei draw_count, unsigned user_buffer_mask,
@@ -472,6 +472,11 @@ multi_draw_arrays_async(struct gl_context *ctx, GLenum mode,
                   first_size + count_size + buffers_size;
    struct marshal_cmd_MultiDrawArrays *cmd;
 
+   /* Make sure cmd can fit the queue buffer */
+   if (cmd_size > MARSHAL_MAX_CMD_SIZE) {
+      return false;
+   }
+
    cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawArrays,
                                          cmd_size);
    cmd->mode = mode;
@@ -487,6 +492,8 @@ multi_draw_arrays_async(struct gl_context *ctx, GLenum mode,
       variable_data += count_size;
       memcpy(variable_data, buffers, buffers_size);
    }
+
+   return true;
 }
 
 void GLAPIENTRY
@@ -502,8 +509,8 @@ _mesa_marshal_MultiDrawArrays(GLenum mode, const GLint *first,
       goto sync;
 
    if (draw_count >= 0 &&
-       (ctx->API == API_OPENGL_CORE || !user_buffer_mask)) {
-      multi_draw_arrays_async(ctx, mode, first, count, draw_count, 0, NULL);
+       (ctx->API == API_OPENGL_CORE || !user_buffer_mask) &&
+       multi_draw_arrays_async(ctx, mode, first, count, draw_count, 0, NULL)) {
       return;
    }
 
@@ -938,7 +945,7 @@ _mesa_unmarshal_MultiDrawElementsBaseVertex(struct gl_context *ctx,
    return cmd->cmd_base.cmd_size;
 }
 
-static ALWAYS_INLINE void
+static ALWAYS_INLINE bool
 multi_draw_elements_async(struct gl_context *ctx, GLenum mode,
                           const GLsizei *count, GLenum type,
                           const GLvoid *const *indices, GLsizei draw_count,
@@ -955,6 +962,11 @@ multi_draw_elements_async(struct gl_context *ctx, GLenum mode,
                   count_size + indices_size + basevertex_size + buffers_size;
    struct marshal_cmd_MultiDrawElementsBaseVertex *cmd;
 
+   /* Make sure cmd can fit the queue buffer */
+   if (cmd_size > MARSHAL_MAX_CMD_SIZE) {
+      return false;
+   }
+
    cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawElementsBaseVertex, cmd_size);
    cmd->mode = mode;
    cmd->type = type;
@@ -976,6 +988,8 @@ multi_draw_elements_async(struct gl_context *ctx, GLenum mode,
 
    if (user_buffer_mask)
       memcpy(variable_data, buffers, buffers_size);
+
+   return true;
 }
 
 void GLAPIENTRY
@@ -999,9 +1013,9 @@ _mesa_marshal_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,
        (ctx->API == API_OPENGL_CORE ||
         !is_index_type_valid(type) ||
         (!user_buffer_mask && !has_user_indices))) {
-      multi_draw_elements_async(ctx, mode, count, type, indices, draw_count,
-                                basevertex, NULL, 0, NULL);
-      return;
+      if (multi_draw_elements_async(ctx, mode, count, type, indices,
+                              draw_count, basevertex, NULL, 0, NULL))
+         return;
    }
 
    bool need_index_bounds = user_buffer_mask & ~vao->NonZeroDivisorMask;
diff --git a/src/mesa/main/glthread_marshal.h b/src/mesa/main/glthread_marshal.h
index 67fa1e0e097..aac940dc08c 100644
--- a/src/mesa/main/glthread_marshal.h
+++ b/src/mesa/main/glthread_marshal.h
@@ -59,6 +59,8 @@ _mesa_glthread_allocate_command(struct gl_context *ctx,
    struct glthread_state *glthread = &ctx->GLThread;
    const unsigned num_elements = align(size, 8) / 8;
 
+   assert (num_elements <= MARSHAL_MAX_CMD_SIZE / 8);
+
    if (unlikely(glthread->used + num_elements > MARSHAL_MAX_CMD_SIZE / 8))
       _mesa_glthread_flush_batch(ctx);
 



More information about the mesa-commit mailing list