llvmpipe: memcpy user_buffers at set_constant_buffer time.
authorEmma Anholt <emma@anholt.net>
Fri, 3 Sep 2021 17:54:36 +0000 (10:54 -0700)
committerMarge Bot <eric+marge@anholt.net>
Tue, 7 Sep 2021 19:16:32 +0000 (19:16 +0000)
The data in the user buffer is only valid for a short period of time, and
we could use-after-free it if rendering hadn't been flushed by shader
deletion time.

Fixes: #5254
Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12724>

src/gallium/drivers/llvmpipe/ci/deqp-llvmpipe-asan-fails.txt [deleted file]
src/gallium/drivers/llvmpipe/lp_state_fs.c

diff --git a/src/gallium/drivers/llvmpipe/ci/deqp-llvmpipe-asan-fails.txt b/src/gallium/drivers/llvmpipe/ci/deqp-llvmpipe-asan-fails.txt
deleted file mode 100644 (file)
index a0ac7a4..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-# https://gitlab.freedesktop.org/mesa/mesa/-/issues/5254
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_24_bits.rgb8_rgb8.texture2d_array_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_24_bits.rgb8_rgb8.texture3d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_24_bits.rgb8i_rgb8.cubemap_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_24_bits.rgb8i_rgb8.texture2d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rg16i.texture2d_array_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rg16i.texture3d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rg16ui.texture2d_array_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rg16ui.texture3d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rgb10_a2.texture3d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rgb10_a2ui.texture2d_array_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rgba8i.texture2d_array_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rgba8i.texture3d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rgba8ui.texture2d_array_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rg16i.texture3d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rg16ui.texture2d_array_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rg16ui.texture3d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rgba8.texture3d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rgba8i.texture2d_array_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rgba8i.texture3d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rgba8ui.texture2d_array_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8_r8.texture2d_array_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8_r8.texture3d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8_r8i.texture2d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8_snorm_r8i.cubemap_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8_snorm_r8ui.cubemap_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8_snorm_r8ui.texture2d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8i_r8.cubemap_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8i_r8.texture2d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8i_r8i.texture2d_array_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8i_r8i.texture3d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8i_r8ui.texture2d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8ui_r8.texture2d_array_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8ui_r8i.cubemap_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8ui_r8i.texture2d_to_renderbuffer,Crash
-dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8ui_r8ui.texture3d_to_renderbuffer,Crash
-dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.12,Crash
-dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.2,Crash
index bff4fa8..400eafe 100644 (file)
@@ -67,6 +67,7 @@
 #include "util/u_string.h"
 #include "util/simple_list.h"
 #include "util/u_dual_blend.h"
+#include "util/u_upload_mgr.h"
 #include "util/os_time.h"
 #include "pipe/p_shader_tokens.h"
 #include "draw/draw_context.h"
@@ -3984,7 +3985,7 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
                              const struct pipe_constant_buffer *cb)
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
-   struct pipe_resource *constants = cb ? cb->buffer : NULL;
+   struct pipe_constant_buffer *constants = &llvmpipe->constants[shader][index];
 
    assert(shader < PIPE_SHADER_TYPES);
    assert(index < ARRAY_SIZE(llvmpipe->constants[shader]));
@@ -3993,10 +3994,19 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
    util_copy_constant_buffer(&llvmpipe->constants[shader][index], cb,
                              take_ownership);
 
-   if (constants) {
-       if (!(constants->bind & PIPE_BIND_CONSTANT_BUFFER)) {
+   /* user_buffer is only valid until the next set_constant_buffer (at most,
+    * possibly until shader deletion), so we need to upload it now to make sure
+    * it doesn't get updated/freed out from under us.
+    */
+   if (constants->user_buffer) {
+      u_upload_data(llvmpipe->pipe.const_uploader, 0, constants->buffer_size, 16,
+                    constants->user_buffer, &constants->buffer_offset,
+                    &constants->buffer);
+   }
+   if (constants->buffer) {
+       if (!(constants->buffer->bind & PIPE_BIND_CONSTANT_BUFFER)) {
          debug_printf("Illegal set constant without bind flag\n");
-         constants->bind |= PIPE_BIND_CONSTANT_BUFFER;
+         constants->buffer->bind |= PIPE_BIND_CONSTANT_BUFFER;
       }
    }
 
@@ -4006,20 +4016,10 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
        shader == PIPE_SHADER_TESS_EVAL) {
       /* Pass the constants to the 'draw' module */
       const unsigned size = cb ? cb->buffer_size : 0;
-      const ubyte *data;
 
-      if (constants) {
-         data = (ubyte *) llvmpipe_resource_data(constants);
-      }
-      else if (cb && cb->user_buffer) {
-         data = (ubyte *) cb->user_buffer;
-      }
-      else {
-         data = NULL;
-      }
-
-      if (data)
-         data += cb->buffer_offset;
+      const ubyte *data = NULL;
+      if (constants->buffer)
+         data = (ubyte *) llvmpipe_resource_data(constants->buffer) + constants->buffer_offset;
 
       draw_set_mapped_constant_buffer(llvmpipe->draw, shader,
                                       index, data, size);
@@ -4028,10 +4028,6 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
       llvmpipe->cs_dirty |= LP_CSNEW_CONSTANTS;
    else
       llvmpipe->dirty |= LP_NEW_FS_CONSTANTS;
-
-   if (cb && cb->user_buffer) {
-      pipe_resource_reference(&constants, NULL);
-   }
 }
 
 static void